Move third column from HistoryWidget to MainWidget.

This commit is contained in:
John Preston 2017-09-16 19:53:41 +03:00
parent f162462111
commit 5e7aa4ff81
63 changed files with 1187 additions and 752 deletions

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include <rpl/event_stream.h>
#include "base/timer.h" #include "base/timer.h"
#include "core/single_timer.h" #include "core/single_timer.h"
#include "mtproto/sender.h" #include "mtproto/sender.h"
@ -132,6 +133,13 @@ public:
not_null<UserData*> user, not_null<UserData*> user,
PhotoId afterId); PhotoId afterId);
void stickerSetInstalled(uint64 setId) {
_stickerSetInstalled.fire_copy(setId);
}
rpl::producer<uint64> stickerSetInstalled() const {
return _stickerSetInstalled.events();
}
~ApiWrap(); ~ApiWrap();
private: private:
@ -262,4 +270,6 @@ private:
base::Observable<PeerData*> _fullPeerUpdated; base::Observable<PeerData*> _fullPeerUpdated;
rpl::event_stream<uint64> _stickerSetInstalled;
}; };

View File

@ -71,6 +71,7 @@ QByteArray AuthSessionData::serialize() const {
for (auto peerId : _variables.groupStickersSectionHidden) { for (auto peerId : _variables.groupStickersSectionHidden) {
stream << quint64(peerId); stream << quint64(peerId);
} }
stream << qint32(_variables.thirdSectionInfoEnabled ? 1 : 0);
} }
return result; return result;
} }
@ -89,7 +90,8 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
qint32 floatPlayerColumn = static_cast<qint32>(Window::Column::Second); qint32 floatPlayerColumn = static_cast<qint32>(Window::Column::Second);
qint32 floatPlayerCorner = static_cast<qint32>(RectPart::TopRight); qint32 floatPlayerCorner = static_cast<qint32>(RectPart::TopRight);
QMap<QString, QString> soundOverrides; QMap<QString, QString> soundOverrides;
OrderedSet<PeerId> groupStickersSectionHidden; base::flat_set<PeerId> groupStickersSectionHidden;
qint32 thirdSectionInfoEnabled = 0;
stream >> selectorTab; stream >> selectorTab;
stream >> lastSeenWarningSeen; stream >> lastSeenWarningSeen;
if (!stream.atEnd()) { if (!stream.atEnd()) {
@ -123,6 +125,9 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
} }
} }
} }
if (!stream.atEnd()) {
stream >> thirdSectionInfoEnabled;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()")); LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
return; return;
@ -152,6 +157,24 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
case RectPart::BottomRight: _variables.floatPlayerCorner = uncheckedCorner; break; case RectPart::BottomRight: _variables.floatPlayerCorner = uncheckedCorner; break;
} }
_variables.groupStickersSectionHidden = std::move(groupStickersSectionHidden); _variables.groupStickersSectionHidden = std::move(groupStickersSectionHidden);
_variables.thirdSectionInfoEnabled = thirdSectionInfoEnabled;
}
void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
_variables.tabbedSelectorSectionEnabled = enabled;
if (enabled) {
setThirdSectionInfoEnabled(false);
}
}
void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
if (_variables.thirdSectionInfoEnabled != enabled) {
_variables.thirdSectionInfoEnabled = enabled;
if (enabled) {
setTabbedSelectorSectionEnabled(false);
}
_thirdSectionInfoEnabledValue.fire_copy(enabled);
}
} }
QString AuthSessionData::getSoundPath(const QString &key) const { QString AuthSessionData::getSoundPath(const QString &key) const {

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include <rpl/event_stream.h>
#include "base/timer.h" #include "base/timer.h"
namespace Storage { namespace Storage {
@ -100,8 +101,14 @@ public:
bool tabbedSelectorSectionEnabled() const { bool tabbedSelectorSectionEnabled() const {
return _variables.tabbedSelectorSectionEnabled; return _variables.tabbedSelectorSectionEnabled;
} }
void setTabbedSelectorSectionEnabled(bool enabled) { void setTabbedSelectorSectionEnabled(bool enabled);
_variables.tabbedSelectorSectionEnabled = enabled; bool thirdSectionInfoEnabled() const {
return _variables.thirdSectionInfoEnabled;
}
void setThirdSectionInfoEnabled(bool enabled);
rpl::producer<bool> thirdSectionInfoEnabledValue() const {
return _thirdSectionInfoEnabledValue.events_starting_with(
thirdSectionInfoEnabled());
} }
void setLastTimeVideoPlayedAt(TimeMs time) { void setLastTimeVideoPlayedAt(TimeMs time) {
_lastTimeVideoPlayedAt = time; _lastTimeVideoPlayedAt = time;
@ -155,7 +162,8 @@ private:
QMap<QString, QString> soundOverrides; QMap<QString, QString> soundOverrides;
Window::Column floatPlayerColumn; Window::Column floatPlayerColumn;
RectPart floatPlayerCorner; RectPart floatPlayerCorner;
OrderedSet<PeerId> groupStickersSectionHidden; base::flat_set<PeerId> groupStickersSectionHidden;
bool thirdSectionInfoEnabled = false;
}; };
base::Variable<bool> _contactsLoaded = { false }; base::Variable<bool> _contactsLoaded = { false };
@ -167,6 +175,8 @@ private:
base::Observable<not_null<const HistoryItem*>> _repaintLogEntry; base::Observable<not_null<const HistoryItem*>> _repaintLogEntry;
base::Observable<void> _pendingHistoryResize; base::Observable<void> _pendingHistoryResize;
base::Observable<ItemVisibilityQuery> _queryItemVisibility; base::Observable<ItemVisibilityQuery> _queryItemVisibility;
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
Variables _variables; Variables _variables;
TimeMs _lastTimeVideoPlayedAt = 0; TimeMs _lastTimeVideoPlayedAt = 0;

View File

@ -56,12 +56,12 @@ void StickerSetBox::prepare() {
onUpdateButtons(); onUpdateButtons();
connect(_inner, SIGNAL(updateButtons()), this, SLOT(onUpdateButtons())); connect(_inner, SIGNAL(updateButtons()), this, SLOT(onUpdateButtons()));
connect(_inner, SIGNAL(installed(uint64)), this, SLOT(onInstalled(uint64))); _inner->setInstalled()
} | rpl::on_next([this](auto &&setId) {
Auth().api().stickerSetInstalled(setId);
void StickerSetBox::onInstalled(uint64 setId) { closeBox();
emit installed(setId); })
closeBox(); | rpl::start(lifetime());
} }
void StickerSetBox::onAddStickers() { void StickerSetBox::onAddStickers() {
@ -250,7 +250,7 @@ void StickerSetBox::Inner::installDone(const MTPmessages_StickerSetInstallResult
Local::writeInstalledStickers(); Local::writeInstalledStickers();
Auth().data().stickersUpdated().notify(true); Auth().data().stickersUpdated().notify(true);
} }
emit installed(_setId); _setInstalled.fire_copy(_setId);
} }
bool StickerSetBox::Inner::installFail(const RPCError &error) { bool StickerSetBox::Inner::installFail(const RPCError &error) {

View File

@ -35,9 +35,6 @@ class StickerSetBox : public BoxContent, public RPCSender {
public: public:
StickerSetBox(QWidget*, const MTPInputStickerSet &set); StickerSetBox(QWidget*, const MTPInputStickerSet &set);
signals:
void installed(uint64 id);
protected: protected:
void prepare() override; void prepare() override;
@ -48,8 +45,6 @@ private slots:
void onShareStickers(); void onShareStickers();
void onUpdateButtons(); void onUpdateButtons();
void onInstalled(uint64 id);
private: private:
void updateButtons(); void updateButtons();
@ -74,6 +69,9 @@ public:
QString shortName() const; QString shortName() const;
void install(); void install();
rpl::producer<uint64> setInstalled() const {
return _setInstalled.events();
}
~Inner(); ~Inner();
@ -89,7 +87,6 @@ private slots:
signals: signals:
void updateButtons(); void updateButtons();
void installed(uint64 id);
private: private:
void updateSelected(); void updateSelected();
@ -127,4 +124,6 @@ private:
QTimer _previewTimer; QTimer _previewTimer;
int _previewShown = -1; int _previewShown = -1;
rpl::event_stream<uint64> _setInstalled;
}; };

View File

@ -1094,7 +1094,7 @@ void StickersBox::Inner::saveGroupSet() {
auto newId = (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0; auto newId = (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0;
if (newId != oldId) { if (newId != oldId) {
Auth().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput); Auth().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput);
App::main()->onStickersInstalled(Stickers::MegagroupSetId); Auth().api().stickerSetInstalled(Stickers::MegagroupSetId);
} }
} }

View File

@ -304,7 +304,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller) EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
, _picker(this) { , _picker(this) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight()); updateSize();
setMouseTracking(true); setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
@ -381,7 +381,7 @@ EmojiListWidget::SectionInfo EmojiListWidget::sectionInfoByOffset(int yOffset) c
return result; return result;
} }
int EmojiListWidget::countHeight() { int EmojiListWidget::countDesiredHeight() {
return sectionInfo(kEmojiSectionCount - 1).rowsBottom + st::emojiPanPadding; return sectionInfo(kEmojiSectionCount - 1).rowsBottom + st::emojiPanPadding;
} }
@ -648,11 +648,7 @@ void EmojiListWidget::refreshRecent() {
clearSelection(); clearSelection();
_emoji[0] = Ui::Emoji::GetSection(Section::Recent); _emoji[0] = Ui::Emoji::GetSection(Section::Recent);
_counts[0] = _emoji[0].size(); _counts[0] = _emoji[0].size();
auto h = countHeight(); updateSize();
if (h != height()) {
resize(width(), h);
update();
}
} }
bool EmojiListWidget::event(QEvent *e) { bool EmojiListWidget::event(QEvent *e) {

View File

@ -126,7 +126,7 @@ protected:
TabbedSelector::InnerFooter *getFooter() const override; TabbedSelector::InnerFooter *getFooter() const override;
void processHideFinished() override; void processHideFinished() override;
int countHeight() override; int countDesiredHeight() override;
private: private:
class Footer; class Footer;

View File

@ -122,7 +122,7 @@ void GifsListWidget::Footer::processPanelHideFinished() {
GifsListWidget::GifsListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller) GifsListWidget::GifsListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
, _section(Section::Gifs) { , _section(Section::Gifs) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight()); updateSize();
setMouseTracking(true); setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
@ -174,17 +174,12 @@ void GifsListWidget::checkLoadMore() {
} }
} }
int GifsListWidget::countHeight() { int GifsListWidget::countDesiredHeight() {
auto visibleHeight = getVisibleBottom() - getVisibleTop();
if (visibleHeight <= 0) {
visibleHeight = st::emojiPanMaxHeight - st::emojiCategory.height;
}
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
auto result = st::stickerPanPadding; auto result = st::stickerPanPadding;
for (int i = 0, l = _rows.count(); i < l; ++i) { for (int i = 0, l = _rows.count(); i < l; ++i) {
result += _rows[i].height; result += _rows[i].height;
} }
return qMax(minimalLastHeight, result) + st::stickerPanPadding; return result + st::stickerPanPadding;
} }
GifsListWidget::~GifsListWidget() { GifsListWidget::~GifsListWidget() {
@ -475,11 +470,7 @@ void GifsListWidget::refreshSavedGifs() {
} }
deleteUnusedGifLayouts(); deleteUnusedGifLayouts();
auto newHeight = countHeight(); updateSize();
if (newHeight != height()) {
resize(width(), newHeight);
}
update(); update();
} }
@ -642,8 +633,7 @@ int GifsListWidget::refreshInlineRows(const InlineCacheEntry *entry, bool result
inlineRowFinalize(row, sumWidth, true); inlineRowFinalize(row, sumWidth, true);
} }
int32 h = countHeight(); updateSize();
if (h != height()) resize(width(), h);
update(); update();
_lastMousePos = QCursor::pos(); _lastMousePos = QCursor::pos();

View File

@ -82,7 +82,7 @@ protected:
TabbedSelector::InnerFooter *getFooter() const override; TabbedSelector::InnerFooter *getFooter() const override;
void processHideFinished() override; void processHideFinished() override;
void processPanelHideFinished() override; void processPanelHideFinished() override;
int countHeight() override; int countDesiredHeight() override;
private slots: private slots:
void onPreview(); void onPreview();

View File

@ -262,7 +262,7 @@ void SetIsFaved(not_null<DocumentData*> document, base::optional<std::vector<not
} }
Local::writeFavedStickers(); Local::writeFavedStickers();
Auth().data().stickersUpdated().notify(true); Auth().data().stickersUpdated().notify(true);
App::main()->onStickersInstalled(FavedSetId); Auth().api().stickerSetInstalled(FavedSetId);
} }
void RequestSetToPushFaved(not_null<DocumentData*> document) { void RequestSetToPushFaved(not_null<DocumentData*> document) {

View File

@ -440,7 +440,7 @@ StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Control
, _addText(lang(lng_stickers_featured_add).toUpper()) , _addText(lang(lng_stickers_featured_add).toUpper())
, _addWidth(st::stickersTrendingAdd.font->width(_addText)) , _addWidth(st::stickersTrendingAdd.font->width(_addText))
, _settings(this, lang(lng_stickers_you_have)) { , _settings(this, lang(lng_stickers_you_have)) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight()); updateSize();
setMouseTracking(true); setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
@ -559,11 +559,8 @@ StickersListWidget::SectionInfo StickersListWidget::sectionInfoByOffset(int yOff
return result; return result;
} }
int StickersListWidget::countHeight() { int StickersListWidget::countDesiredHeight() {
auto visibleHeight = getVisibleBottom() - getVisibleTop(); auto visibleHeight = minimalHeight();
if (visibleHeight <= 0) {
visibleHeight = st::emojiPanMaxHeight - st::emojiCategory.height;
}
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding); auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
auto countResult = [this, minimalLastHeight] { auto countResult = [this, minimalLastHeight] {
if (_section == Section::Featured) { if (_section == Section::Featured) {
@ -1154,10 +1151,7 @@ void StickersListWidget::refreshStickers() {
appendSet(_featuredSets, setId, AppendSkip::Installed); appendSet(_featuredSets, setId, AppendSkip::Installed);
} }
auto newHeight = countHeight(); updateSize();
if (newHeight != height()) {
resize(width(), newHeight);
}
if (_footer) { if (_footer) {
_footer->refreshIcons(ValidateIconAnimations::None); _footer->refreshIcons(ValidateIconAnimations::None);
@ -1283,12 +1277,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
} }
if (performResize && (_section == Section::Stickers || _section == Section::Featured)) { if (performResize && (_section == Section::Stickers || _section == Section::Featured)) {
int32 h = countHeight(); updateSize();
if (h != height()) {
resize(width(), h);
update();
}
updateSelected(); updateSelected();
} }
} }

View File

@ -79,7 +79,7 @@ protected:
TabbedSelector::InnerFooter *getFooter() const override; TabbedSelector::InnerFooter *getFooter() const override;
void processHideFinished() override; void processHideFinished() override;
void processPanelHideFinished() override; void processPanelHideFinished() override;
int countHeight() override; int countDesiredHeight() override;
private slots: private slots:
void onSettings(); void onSettings();

View File

@ -34,10 +34,20 @@ constexpr auto kDelayedHideTimeoutMs = 3000;
} // namespace } // namespace
TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controller) : TabbedPanel(parent, controller, object_ptr<TabbedSelector>(nullptr, controller)) { TabbedPanel::TabbedPanel(
QWidget *parent,
not_null<Window::Controller*> controller)
: TabbedPanel(
parent,
controller,
object_ptr<TabbedSelector>(nullptr, controller)) {
} }
TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : TWidget(parent) TabbedPanel::TabbedPanel(
QWidget *parent,
not_null<Window::Controller*> controller,
object_ptr<TabbedSelector> selector)
: RpWidget(parent)
, _controller(controller) , _controller(controller)
, _selector(std::move(selector)) { , _selector(std::move(selector)) {
_selector->setParent(this); _selector->setParent(this);
@ -52,6 +62,9 @@ TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controll
_controller->disableGifPauseReason(Window::GifPauseReason::SavedGifs); _controller->disableGifPauseReason(Window::GifPauseReason::SavedGifs);
} }
}); });
_selector->showRequests()
| rpl::on_next([this](auto&&) { showFromSelector(); })
| rpl::start(lifetime());
resize(QRect(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight).marginsAdded(innerPadding()).size()); resize(QRect(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight).marginsAdded(innerPadding()).size());
@ -376,11 +389,7 @@ bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
return false; return false;
} }
void TabbedPanel::stickersInstalled(uint64 setId) { void TabbedPanel::showFromSelector() {
if (isDestroying()) {
return;
}
_selector->stickersInstalled(setId);
if (isHidden()) { if (isHidden()) {
moveByBottom(); moveByBottom();
startShowAnimation(); startShowAnimation();

View File

@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include "ui/twidget.h" #include "ui/rp_widget.h"
#include "base/timer.h" #include "base/timer.h"
namespace Window { namespace Window {
@ -35,7 +35,7 @@ namespace ChatHelpers {
class TabbedSelector; class TabbedSelector;
class TabbedPanel : public TWidget { class TabbedPanel : public Ui::RpWidget{
Q_OBJECT Q_OBJECT
public: public:
@ -51,8 +51,6 @@ public:
return _hiding || _hideTimer.isActive(); return _hiding || _hideTimer.isActive();
} }
void stickersInstalled(uint64 setId);
bool overlaps(const QRect &globalRect) const; bool overlaps(const QRect &globalRect) const;
void showAnimated(); void showAnimated();
@ -79,6 +77,7 @@ private:
bool isDestroying() const { bool isDestroying() const {
return !_selector; return !_selector;
} }
void showFromSelector();
style::margins innerPadding() const; style::margins innerPadding() const;

View File

@ -25,11 +25,49 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace ChatHelpers { namespace ChatHelpers {
TabbedSection::TabbedSection(QWidget *parent, not_null<Window::Controller*> controller) : TabbedSection(parent, controller, object_ptr<TabbedSelector>(this, controller)) { TabbedMemento::TabbedMemento(
object_ptr<TabbedSelector> selector,
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod)
: _selector(std::move(selector))
, _returnMethod(std::move(returnMethod)) {
} }
TabbedSection::TabbedSection(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : Window::AbstractSectionWidget(parent, controller) object_ptr<Window::SectionWidget> TabbedMemento::createWidget(
, _selector(std::move(selector)) { QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) {
return object_ptr<TabbedSection>(
parent,
controller,
std::move(_selector),
std::move(_returnMethod));
}
TabbedMemento::~TabbedMemento() {
if (_returnMethod && _selector) {
_returnMethod(std::move(_selector));
}
}
TabbedSection::TabbedSection(
QWidget *parent,
not_null<Window::Controller*> controller)
: TabbedSection(
parent,
controller,
object_ptr<TabbedSelector>(this, controller),
base::lambda<void(object_ptr<TabbedSelector>)>()) {
}
TabbedSection::TabbedSection(
QWidget *parent,
not_null<Window::Controller*> controller,
object_ptr<TabbedSelector> selector,
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod)
: Window::SectionWidget(parent, controller)
, _selector(std::move(selector))
, _returnMethod(std::move(returnMethod)) {
resize(st::emojiPanWidth, st::emojiPanMaxHeight); resize(st::emojiPanWidth, st::emojiPanMaxHeight);
_selector->setParent(this); _selector->setParent(this);
@ -68,17 +106,24 @@ object_ptr<TabbedSelector> TabbedSection::takeSelector() {
QPointer<TabbedSelector> TabbedSection::getSelector() const { QPointer<TabbedSelector> TabbedSection::getSelector() const {
return _selector.data(); return _selector.data();
} }
bool TabbedSection::showInternal(
void TabbedSection::stickersInstalled(uint64 setId) { not_null<Window::SectionMemento*> memento) {
_selector->stickersInstalled(setId); return false;
} }
bool TabbedSection::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool TabbedSection::wheelEventFromFloatPlayer(QEvent *e) {
return _selector->wheelEventFromFloatPlayer(e); return _selector->wheelEventFromFloatPlayer(e);
} }
QRect TabbedSection::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect TabbedSection::rectForFloatPlayer() const {
return _selector->rectForFloatPlayer(); return _selector->rectForFloatPlayer();
} }
TabbedSection::~TabbedSection() {
beforeHiding();
if (_returnMethod) {
_returnMethod(takeSelector());
}
}
} // namespace ChatHelpers } // namespace ChatHelpers

View File

@ -21,15 +21,42 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once #pragma once
#include "window/section_widget.h" #include "window/section_widget.h"
#include "window/section_memento.h"
namespace ChatHelpers { namespace ChatHelpers {
class TabbedSelector; class TabbedSelector;
class TabbedSection : public Window::AbstractSectionWidget { class TabbedMemento : public Window::SectionMemento {
public: public:
TabbedSection(QWidget *parent, not_null<Window::Controller*> controller); TabbedMemento(
TabbedSection(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector); object_ptr<TabbedSelector> selector,
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod);
object_ptr<Window::SectionWidget> createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override;
~TabbedMemento();
private:
object_ptr<TabbedSelector> _selector;
base::lambda<void(object_ptr<TabbedSelector>)> _returnMethod;
};
class TabbedSection : public Window::SectionWidget {
public:
TabbedSection(
QWidget *parent,
not_null<Window::Controller*> controller);
TabbedSection(
QWidget *parent,
not_null<Window::Controller*> controller,
object_ptr<TabbedSelector> selector,
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod);
void beforeHiding(); void beforeHiding();
void afterShown(); void afterShown();
@ -40,18 +67,28 @@ public:
object_ptr<TabbedSelector> takeSelector(); object_ptr<TabbedSelector> takeSelector();
QPointer<TabbedSelector> getSelector() const; QPointer<TabbedSelector> getSelector() const;
void stickersInstalled(uint64 setId); bool showInternal(
not_null<Window::SectionMemento*> memento) override;
bool forceAnimateBack() const override {
return true;
}
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
~TabbedSection();
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void showFinishedHook() override {
afterShown();
}
private: private:
object_ptr<TabbedSelector> _selector; object_ptr<TabbedSelector> _selector;
base::lambda<void()> _cancelledCallback; base::lambda<void()> _cancelledCallback;
base::lambda<void(object_ptr<TabbedSelector>)> _returnMethod;
}; };

View File

@ -346,6 +346,14 @@ TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> co
} }
})); }));
Auth().api().stickerSetInstalled()
| rpl::on_next([this](uint64 setId) {
_tabsSlider->setActiveSection(static_cast<int>(SelectorTab::Stickers));
stickers()->showStickerSet(setId);
_showRequests.fire({});
})
| rpl::start(lifetime());
// setAttribute(Qt::WA_AcceptTouchEvents); // setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_OpaquePaintEvent, false);
showAll(); showAll();
@ -356,9 +364,11 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
if (e->oldSize().height() > height()) { if (e->oldSize().height() > height()) {
_scroll->resize(_scroll->width(), contentHeight); _scroll->resize(_scroll->width(), contentHeight);
auto scrollTop = _scroll->scrollTop(); auto scrollTop = _scroll->scrollTop();
currentTab()->widget()->setMinimalHeight(contentHeight);
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight); currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
} else { } else {
auto scrollTop = _scroll->scrollTop(); auto scrollTop = _scroll->scrollTop();
currentTab()->widget()->setMinimalHeight(contentHeight);
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight); currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
_scroll->resize(_scroll->width(), contentHeight); _scroll->resize(_scroll->width(), contentHeight);
} }
@ -514,11 +524,6 @@ void TabbedSelector::afterShown() {
} }
} }
void TabbedSelector::stickersInstalled(uint64 setId) {
_tabsSlider->setActiveSection(static_cast<int>(SelectorTab::Stickers));
stickers()->showStickerSet(setId);
}
void TabbedSelector::showMegagroupSet(ChannelData *megagroup) { void TabbedSelector::showMegagroupSet(ChannelData *megagroup) {
stickers()->showMegagroupSet(megagroup); stickers()->showMegagroupSet(megagroup);
} }
@ -702,15 +707,36 @@ TabbedSelector::Inner::Inner(QWidget *parent, not_null<Window::Controller*> cont
} }
void TabbedSelector::Inner::visibleTopBottomUpdated(int visibleTop, int visibleBottom) { void TabbedSelector::Inner::visibleTopBottomUpdated(int visibleTop, int visibleBottom) {
auto oldVisibleHeight = getVisibleBottom() - getVisibleTop();
_visibleTop = visibleTop; _visibleTop = visibleTop;
_visibleBottom = visibleBottom; _visibleBottom = visibleBottom;
auto visibleHeight = getVisibleBottom() - getVisibleTop(); }
if (visibleHeight != oldVisibleHeight) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight()); void TabbedSelector::Inner::setMinimalHeight(int newMinimalHeight) {
if (_minimalHeight != newMinimalHeight) {
_minimalHeight = newMinimalHeight;
updateSize();
} }
} }
void TabbedSelector::Inner::updateSize() {
auto width = st::emojiPanWidth
- st::emojiScroll.width
- st::buttonRadius;
auto height = qMax(countDesiredHeight(), minimalHeight());
auto newSize = QSize(width, height);
if (size() != newSize) {
resize(newSize);
update();
}
}
int TabbedSelector::Inner::minimalHeight() const {
auto result = _minimalHeight;
return (_minimalHeight > 0)
? _minimalHeight
: (st::emojiPanMaxHeight - st::emojiCategory.height);
}
void TabbedSelector::Inner::hideFinished() { void TabbedSelector::Inner::hideFinished() {
processHideFinished(); processHideFinished();
if (auto footer = getFooter()) { if (auto footer = getFooter()) {

View File

@ -60,7 +60,6 @@ public:
void setRoundRadius(int radius); void setRoundRadius(int radius);
void refreshStickers(); void refreshStickers();
void stickersInstalled(uint64 setId);
void showMegagroupSet(ChannelData *megagroup); void showMegagroupSet(ChannelData *megagroup);
void setCurrentPeer(PeerData *peer); void setCurrentPeer(PeerData *peer);
@ -88,6 +87,10 @@ public:
bool wheelEventFromFloatPlayer(QEvent *e); bool wheelEventFromFloatPlayer(QEvent *e);
QRect rectForFloatPlayer() const; QRect rectForFloatPlayer() const;
rpl::producer<> showRequests() const {
return _showRequests.events();
}
~TabbedSelector(); ~TabbedSelector();
class Inner; class Inner;
@ -199,6 +202,8 @@ private:
base::lambda<void(SelectorTab)> _afterShownCallback; base::lambda<void(SelectorTab)> _afterShownCallback;
base::lambda<void(SelectorTab)> _beforeHidingCallback; base::lambda<void(SelectorTab)> _beforeHidingCallback;
rpl::event_stream<> _showRequests;
}; };
class TabbedSelector::Inner : public TWidget { class TabbedSelector::Inner : public TWidget {
@ -213,6 +218,7 @@ public:
int getVisibleBottom() const { int getVisibleBottom() const {
return _visibleBottom; return _visibleBottom;
} }
void setMinimalHeight(int newMinimalHeight);
virtual void refreshRecent() = 0; virtual void refreshRecent() = 0;
virtual void preloadImages() { virtual void preloadImages() {
@ -236,12 +242,14 @@ protected:
void visibleTopBottomUpdated( void visibleTopBottomUpdated(
int visibleTop, int visibleTop,
int visibleBottom) override; int visibleBottom) override;
void updateSize();
int minimalHeight() const;
not_null<Window::Controller*> controller() const { not_null<Window::Controller*> controller() const {
return _controller; return _controller;
} }
virtual int countHeight() = 0; virtual int countDesiredHeight() = 0;
virtual InnerFooter *getFooter() const = 0; virtual InnerFooter *getFooter() const = 0;
virtual void processHideFinished() { virtual void processHideFinished() {
} }
@ -253,6 +261,7 @@ private:
int _visibleTop = 0; int _visibleTop = 0;
int _visibleBottom = 0; int _visibleBottom = 0;
int _minimalHeight = 0;
}; };

View File

@ -267,11 +267,11 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition()); _a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
} }
bool DialogsWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool DialogsWidget::wheelEventFromFloatPlayer(QEvent *e) {
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect DialogsWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect DialogsWidget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }

View File

@ -98,8 +98,8 @@ public:
void onSearchMore(); void onSearchMore();
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
void notify_userIsContactChanged(UserData *user, bool fromThisApp); void notify_userIsContactChanged(UserData *user, bool fromThisApp);
void notify_historyMuteUpdated(History *history); void notify_historyMuteUpdated(History *history);

View File

@ -262,17 +262,9 @@ void autoplayMediaInlineAsync(const FullMsgId &msgId) {
} }
void showPeerProfile(const PeerId &peer) { void showPeerProfile(const PeerId &peer) {
//if (auto main = App::main()) { if (auto main = App::main()) {
// main->showWideSection(Profile::SectionMemento(App::peer(peer))); // main->showSection(Profile::SectionMemento(App::peer(peer)));
//} main->showSection(Info::Memento(peer), anim::type::normal);
if (auto window = App::wnd()) {
auto memento = Info::Memento(peer);
if (auto layer = memento.createLayer(window->controller())) {
window->controller()->showSpecialLayer(std::move(layer));
} else {
App::main()->showWideSection(std::move(memento));
}
} }
} }

View File

@ -238,6 +238,7 @@ enum class WindowLayout {
OneColumn, OneColumn,
SmallColumn, SmallColumn,
Normal, Normal,
ThreeColumn,
}; };
enum class ChatLayout { enum class ChatLayout {
@ -424,8 +425,13 @@ inline bool Normal() {
return Global::AdaptiveWindowLayout() == WindowLayout::Normal; return Global::AdaptiveWindowLayout() == WindowLayout::Normal;
} }
inline bool ThreeColumn() {
return Global::AdaptiveWindowLayout() == WindowLayout::ThreeColumn;
}
inline bool ChatNormal() { inline bool ChatNormal() {
return !Global::AdaptiveForWide() || (Global::AdaptiveChatLayout() == ChatLayout::Normal); return !Global::AdaptiveForWide()
|| (Global::AdaptiveChatLayout() == ChatLayout::Normal);
} }
inline bool ChatWide() { inline bool ChatWide() {

View File

@ -22,6 +22,8 @@ using "basic.style";
using "dialogs/dialogs.style"; using "dialogs/dialogs.style";
using "ui/widgets/widgets.style"; using "ui/widgets/widgets.style";
historyMinimalWidth: 380px;
historyScroll: ScrollArea(defaultScrollArea) { historyScroll: ScrollArea(defaultScrollArea) {
bg: historyScrollBg; bg: historyScrollBg;
bgOver: historyScrollBgOver; bgOver: historyScrollBgOver;

View File

@ -88,7 +88,14 @@ private:
}; };
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) { object_ptr<Window::SectionWidget> SectionMemento::createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) {
if (column == Window::Column::Third) {
return nullptr;
}
auto result = object_ptr<Widget>(parent, controller, _channel); auto result = object_ptr<Widget>(parent, controller, _channel);
result->setInternalState(geometry, this); result->setInternalState(geometry, this);
return std::move(result); return std::move(result);
@ -427,11 +434,11 @@ void Widget::showFinishedHook() {
_fixedBar->setAnimatingMode(false); _fixedBar->setAnimatingMode(false);
} }
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect Widget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }

View File

@ -101,8 +101,8 @@ public:
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento); void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
void applyFilter(FilterValue &&value); void applyFilter(FilterValue &&value);
@ -136,7 +136,11 @@ public:
SectionMemento(not_null<ChannelData*> channel) : _channel(channel) { SectionMemento(not_null<ChannelData*> channel) : _channel(channel) {
} }
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override; object_ptr<Window::SectionWidget> createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override;
not_null<ChannelData*> getChannel() const { not_null<ChannelData*> getChannel() const {
return _channel; return _channel;

View File

@ -47,8 +47,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "profile/profile_block_group_members.h" #include "profile/profile_block_group_members.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_section.h"
#include "chat_helpers/tabbed_selector.h" #include "chat_helpers/tabbed_selector.h"
#include "chat_helpers/tabbed_section.h"
#include "chat_helpers/bot_keyboard.h" #include "chat_helpers/bot_keyboard.h"
#include "chat_helpers/message_field.h" #include "chat_helpers/message_field.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
@ -75,101 +75,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "inline_bots/inline_results_widget.h" #include "inline_bots/inline_results_widget.h"
#include "chat_helpers/emoji_suggestions_widget.h" #include "chat_helpers/emoji_suggestions_widget.h"
// Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent.
template <typename Object>
class test_ptr {
public:
test_ptr(std::nullptr_t) {
}
// No default constructor, but constructors with at least
// one argument are simply make functions.
template <typename Parent, typename... Args>
explicit test_ptr(Parent &&parent, Args&&... args) : _object(new Object(std::forward<Parent>(parent), std::forward<Args>(args)...)) {
}
test_ptr(const test_ptr &other) = delete;
test_ptr &operator=(const test_ptr &other) = delete;
test_ptr(test_ptr &&other) : _object(base::take(other._object)) {
}
test_ptr &operator=(test_ptr &&other) {
auto temp = std::move(other);
destroy();
std::swap(_object, temp._object);
return *this;
}
template <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
test_ptr(test_ptr<OtherObject> &&other) : _object(base::take(other._object)) {
}
template <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
test_ptr &operator=(test_ptr<OtherObject> &&other) {
_object = base::take(other._object);
return *this;
}
test_ptr &operator=(std::nullptr_t) {
_object = nullptr;
return *this;
}
// So we can pass this pointer to methods like connect().
Object *data() const {
return static_cast<Object*>(_object);
}
operator Object*() const {
return data();
}
explicit operator bool() const {
return _object != nullptr;
}
Object *operator->() const {
return data();
}
Object &operator*() const {
return *data();
}
// Use that instead "= new Object(parent, ...)"
template <typename Parent, typename... Args>
void create(Parent &&parent, Args&&... args) {
destroy();
_object = new Object(std::forward<Parent>(parent), std::forward<Args>(args)...);
}
void destroy() {
delete base::take(_object);
}
void destroyDelayed() {
if (_object) {
if (auto widget = base::up_cast<QWidget*>(data())) {
widget->hide();
}
base::take(_object)->deleteLater();
}
}
~test_ptr() {
if (auto pointer = _object) {
if (!pointer->parent()) {
destroy();
}
}
}
private:
template <typename OtherObject>
friend class test_ptr;
QPointer<QObject> _object;
};
class TestClass;
test_ptr<TestClass> tmp = { nullptr };
namespace { namespace {
constexpr auto kSaveTabbedSelectorSectionTimeoutMs = 1000; constexpr auto kSaveTabbedSelectorSectionTimeoutMs = 1000;
@ -739,7 +644,9 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
_botCommandStart->hide(); _botCommandStart->hide();
_tabbedSelectorToggle->installEventFilter(_tabbedPanel); _tabbedSelectorToggle->installEventFilter(_tabbedPanel);
_tabbedSelectorToggle->setClickedCallback([this] { toggleTabbedSelectorMode(); }); _tabbedSelectorToggle->setClickedCallback([this] {
toggleTabbedSelectorMode();
});
connect(_botKeyboardShow, SIGNAL(clicked()), this, SLOT(onKbToggle())); connect(_botKeyboardShow, SIGNAL(clicked()), this, SLOT(onKbToggle()));
connect(_botKeyboardHide, SIGNAL(clicked()), this, SLOT(onKbToggle())); connect(_botKeyboardHide, SIGNAL(clicked()), this, SLOT(onKbToggle()));
@ -819,22 +726,6 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
} }
} }
})); }));
subscribe(controller->window()->widgetGrabbed(), [this] {
// Qt bug workaround: QWidget::render() for an arbitrary widget calls
// sendPendingMoveAndResizeEvents(true, true) for the whole window,
// which does something like:
//
// setAttribute(Qt::WA_UpdatesDisabled);
// sendEvent(QResizeEvent);
// setAttribute(Qt::WA_UpdatesDisabled, false);
//
// So if we create TabbedSection widget in HistoryWidget::resizeEvent()
// it will get an enabled Qt::WA_UpdatesDisabled from its parent and it
// will never be rendered, because no one will ever remove that attribute.
//
// So we force HistoryWidget::resizeEvent() here, without WA_UpdatesDisabled.
myEnsureResized(this);
});
subscribe(Auth().data().pendingHistoryResize(), [this] { handlePendingHistoryUpdate(); }); subscribe(Auth().data().pendingHistoryResize(), [this] { handlePendingHistoryUpdate(); });
subscribe(Auth().data().queryItemVisibility(), [this](const AuthSessionData::ItemVisibilityQuery &query) { subscribe(Auth().data().queryItemVisibility(), [this](const AuthSessionData::ItemVisibilityQuery &query) {
if (_a_show.animating() || _history != query.item->history() || query.item->detached() || !isVisible()) { if (_a_show.animating() || _history != query.item->history() || query.item->detached() || !isVisible()) {
@ -1152,9 +1043,6 @@ void HistoryWidget::orderWidgets() {
_reportSpamPanel->raise(); _reportSpamPanel->raise();
} }
_topShadow->raise(); _topShadow->raise();
if (_rightShadow) {
_rightShadow->raise();
}
if (_membersDropdown) { if (_membersDropdown) {
_membersDropdown->raise(); _membersDropdown->raise();
} }
@ -1383,14 +1271,6 @@ void HistoryWidget::updateRecentStickers() {
_tabbedSelector->refreshStickers(); _tabbedSelector->refreshStickers();
} }
void HistoryWidget::stickersInstalled(uint64 setId) {
if (_tabbedPanel) {
_tabbedPanel->stickersInstalled(setId);
} else if (_tabbedSection) {
_tabbedSection->stickersInstalled(setId);
}
}
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) { void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
for (auto i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) { for (auto i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
if (i.value() == req) { if (i.value() == req) {
@ -2108,20 +1988,10 @@ void HistoryWidget::updateControlsVisibility() {
updateHistoryDownVisibility(); updateHistoryDownVisibility();
updateUnreadMentionsVisibility(); updateUnreadMentionsVisibility();
if (!_history || _a_show.animating()) { if (!_history || _a_show.animating()) {
if (_tabbedSection && !_tabbedSection->isHidden()) {
_tabbedSection->beforeHiding();
}
hideChildren(); hideChildren();
return; return;
} }
if (_tabbedSection) {
if (_tabbedSection->isHidden()) {
_tabbedSection->show();
_tabbedSection->afterShown();
}
_rightShadow->show();
}
if (_pinnedBar) { if (_pinnedBar) {
_pinnedBar->cancel->show(); _pinnedBar->cancel->show();
_pinnedBar->shadow->show(); _pinnedBar->shadow->show();
@ -2287,7 +2157,7 @@ void HistoryWidget::updateControlsVisibility() {
update(); update();
} }
} }
checkTabbedSelectorToggleTooltip(); //checkTabbedSelectorToggleTooltip();
updateMouseTracking(); updateMouseTracking();
} }
@ -2807,7 +2677,16 @@ void HistoryWidget::saveEditMsg() {
if (!sentEntities.v.isEmpty()) { if (!sentEntities.v.isEmpty()) {
sendFlags |= MTPmessages_EditMessage::Flag::f_entities; sendFlags |= MTPmessages_EditMessage::Flag::f_entities;
} }
_saveEditMsgRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(sendFlags), _history->peer->input, MTP_int(_editMsgId), MTP_string(sending.text), MTPnullMarkup, sentEntities), rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcFail(&HistoryWidget::saveEditMsgFail, _history)); _saveEditMsgRequestId = MTP::send(
MTPmessages_EditMessage(
MTP_flags(sendFlags),
_history->peer->input,
MTP_int(_editMsgId),
MTP_string(sending.text),
MTPnullMarkup,
sentEntities),
rpcDone(&HistoryWidget::saveEditMsgDone, _history),
rpcFail(&HistoryWidget::saveEditMsgFail, _history));
} }
void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) { void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) {
@ -3077,15 +2956,8 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
_topShadow->setVisible(params.withTopBarShadow ? false : true); _topShadow->setVisible(params.withTopBarShadow ? false : true);
_cacheOver = App::main()->grabForShowAnimation(params); _cacheOver = App::main()->grabForShowAnimation(params);
if (_tabbedSection && !_tabbedSection->isHidden()) {
_tabbedSection->beforeHiding();
}
hideChildren(); hideChildren();
if (params.withTopBarShadow) _topShadow->show(); if (params.withTopBarShadow) _topShadow->show();
if (params.withTabbedSection && _tabbedSection) {
_tabbedSection->show();
_tabbedSection->afterShown();
}
if (_showDirection == Window::SlideDirection::FromLeft) { if (_showDirection == Window::SlideDirection::FromLeft) {
std::swap(_cacheUnder, _cacheOver); std::swap(_cacheUnder, _cacheOver);
@ -3507,19 +3379,11 @@ bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
return TWidget::eventFilter(obj, e); return TWidget::eventFilter(obj, e);
} }
bool HistoryWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool HistoryWidget::wheelEventFromFloatPlayer(QEvent *e) {
if (playerColumn == Window::Column::Third && _tabbedSection) {
auto tabbedColumn = (myColumn == Window::Column::First) ? Window::Column::Second : Window::Column::Third;
return _tabbedSection->wheelEventFromFloatPlayer(e, tabbedColumn, playerColumn);
}
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect HistoryWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect HistoryWidget::rectForFloatPlayer() const {
if (playerColumn == Window::Column::Third && _tabbedSection) {
auto tabbedColumn = (myColumn == Window::Column::First) ? Window::Column::Second : Window::Column::Third;
return _tabbedSection->rectForFloatPlayer(tabbedColumn, playerColumn);
}
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }
@ -3827,7 +3691,7 @@ bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
auto nameleft = st::topBarArrowPadding.right() + increaseLeft; auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
auto nametop = st::topBarArrowPadding.top(); auto nametop = st::topBarArrowPadding.top();
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height; auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
auto namewidth = _chatWidth - decreaseWidth - nameleft - st::topBarArrowPadding.right(); auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) { if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg); p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
@ -3888,113 +3752,66 @@ void HistoryWidget::onModerateKeyActivate(int index, bool *outHandled) {
void HistoryWidget::topBarClick() { void HistoryWidget::topBarClick() {
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
App::main()->showBackFromStack(); App::main()->showBackFromStack();
} else { } else if (_peer) {
if (_history) Ui::showPeerProfile(_peer); controller()->showPeerInfo(_peer);
} }
} }
void HistoryWidget::updateTabbedSelectorSectionShown() { void HistoryWidget::pushTabbedSelectorToThirdSection() {
auto tabbedSelectorSectionEnabled = Auth().data().tabbedSelectorSectionEnabled(); if (!_history || !_tabbedPanel) {
auto useTabbedSection = tabbedSelectorSectionEnabled && (width() >= minimalWidthForTabbedSelectorSection());
if (_tabbedSectionUsed == useTabbedSection) {
return; return;
} }
_tabbedSectionUsed = useTabbedSection; _tabbedSelectorToggle->setColorOverrides(
&st::historyAttachEmojiActive,
&st::historyRecordVoiceFgActive,
&st::historyRecordVoiceRippleBgActive);
auto destroyingPanel = std::move(_tabbedPanel);
controller()->resizeForThirdSection();
controller()->showSection(ChatHelpers::TabbedMemento(
destroyingPanel->takeSelector(),
base::lambda_guarded(this, [this](
object_ptr<TabbedSelector> selector) {
returnTabbedSelector(std::move(selector));
})));
}
// Use a separate bool flag instead of just (_tabbedSection != nullptr), because void HistoryWidget::pushInfoToThirdSection() {
// _tabbedPanel->takeSelector() calls QWidget::render(), which calls if (!_peer) {
// sendPendingMoveAndResizeEvents() for all widgets in the window, which can lead return;
// to a new HistoryWidget::resizeEvent() call and an infinite recursion here.
if (_tabbedSectionUsed) {
_tabbedSection.create(this, controller(), _tabbedPanel->takeSelector());
_tabbedSection->setCancelledCallback([this] { setInnerFocus(); });
_tabbedSelectorToggle->setColorOverrides(&st::historyAttachEmojiActive, &st::historyRecordVoiceFgActive, &st::historyRecordVoiceRippleBgActive);
_rightShadow.create(this, st::shadowFg);
auto destroyingPanel = std::move(_tabbedPanel);
updateControlsVisibility();
} else {
_tabbedPanel.create(this, controller(), _tabbedSection->takeSelector());
_tabbedPanel->hide();
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
_tabbedSection.destroy();
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
_rightShadow.destroy();
_tabbedSelectorToggleTooltipShown = false;
} }
checkTabbedSelectorToggleTooltip(); controller()->showPeerInfo(_peer);
orderWidgets();
}
void HistoryWidget::checkTabbedSelectorToggleTooltip() {
if (_tabbedSection && !_tabbedSection->isHidden() && !_tabbedSelectorToggle->isHidden()) {
if (!_tabbedSelectorToggleTooltipShown) {
auto shownCount = Auth().data().tabbedSelectorSectionTooltipShown();
if (shownCount < kTabbedSelectorToggleTooltipCount) {
_tabbedSelectorToggleTooltipShown = true;
_tabbedSelectorToggleTooltip.create(this, object_ptr<Ui::FlatLabel>(this, lang(lng_emoji_hide_panel), Ui::FlatLabel::InitType::Simple, st::defaultImportantTooltipLabel), st::defaultImportantTooltip);
_tabbedSelectorToggleTooltip->setHiddenCallback([this] {
_tabbedSelectorToggleTooltip.destroy();
});
InvokeQueued(_tabbedSelectorToggleTooltip, [this, shownCount] {
Auth().data().setTabbedSelectorSectionTooltipShown(shownCount + 1);
Auth().saveDataDelayed(kTabbedSelectorToggleTooltipTimeoutMs);
updateTabbedSelectorToggleTooltipGeometry();
_tabbedSelectorToggleTooltip->hideAfter(kTabbedSelectorToggleTooltipTimeoutMs);
_tabbedSelectorToggleTooltip->toggleAnimated(true);
});
}
}
} else {
_tabbedSelectorToggleTooltip.destroy();
}
}
int HistoryWidget::tabbedSelectorSectionWidth() const {
return st::emojiPanWidth;
}
int HistoryWidget::minimalWidthForTabbedSelectorSection() const {
return st::windowMinWidth + tabbedSelectorSectionWidth();
}
bool HistoryWidget::willSwitchToTabbedSelectorWithWidth(int newWidth) const {
if (!Auth().data().tabbedSelectorSectionEnabled()) {
return false;
} else if (_tabbedSectionUsed) {
return false;
}
return (newWidth >= minimalWidthForTabbedSelectorSection());
} }
void HistoryWidget::toggleTabbedSelectorMode() { void HistoryWidget::toggleTabbedSelectorMode() {
if (_tabbedSection) { if (_tabbedPanel) {
Auth().data().setTabbedSelectorSectionEnabled(false); if (controller()->canShowThirdSection()) {
Auth().saveDataDelayed(kSaveTabbedSelectorSectionTimeoutMs);
updateTabbedSelectorSectionShown();
recountChatWidth();
updateControlsGeometry();
} else if (controller()->canProvideChatWidth(minimalWidthForTabbedSelectorSection())) {
if (!Auth().data().tabbedSelectorSectionEnabled()) {
Auth().data().setTabbedSelectorSectionEnabled(true); Auth().data().setTabbedSelectorSectionEnabled(true);
Auth().saveDataDelayed(kSaveTabbedSelectorSectionTimeoutMs); Auth().saveDataDelayed(kSaveTabbedSelectorSectionTimeoutMs);
pushTabbedSelectorToThirdSection();
} else {
_tabbedPanel->toggleAnimated();
} }
controller()->provideChatWidth(minimalWidthForTabbedSelectorSection());
updateTabbedSelectorSectionShown();
recountChatWidth();
updateControlsGeometry();
} else { } else {
Assert(_tabbedPanel != nullptr); controller()->closeThirdSection();
_tabbedPanel->toggleAnimated();
} }
} }
void HistoryWidget::returnTabbedSelector(
object_ptr<TabbedSelector> selector) {
_tabbedPanel.create(
this,
controller(),
std::move(selector));
_tabbedPanel->hide();
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
_tabbedSelectorToggleTooltipShown = false;
}
void HistoryWidget::recountChatWidth() { void HistoryWidget::recountChatWidth() {
_chatWidth = width(); auto layout = (width() < st::adaptiveChatWideWidth)
if (_tabbedSection) { ? Adaptive::ChatLayout::Normal
_chatWidth -= _tabbedSection->width(); : Adaptive::ChatLayout::Wide;
}
auto layout = (_chatWidth < st::adaptiveChatWideWidth) ? Adaptive::ChatLayout::Normal : Adaptive::ChatLayout::Wide;
if (layout != Global::AdaptiveChatLayout()) { if (layout != Global::AdaptiveChatLayout()) {
Global::SetAdaptiveChatLayout(layout); Global::SetAdaptiveChatLayout(layout);
Adaptive::Changed().notify(true); Adaptive::Changed().notify(true);
@ -4106,11 +3923,11 @@ void HistoryWidget::moveFieldControls() {
auto keyboardHeight = 0; auto keyboardHeight = 0;
auto bottom = height(); auto bottom = height();
auto maxKeyboardHeight = st::historyComposeFieldMaxHeight - _field->height(); auto maxKeyboardHeight = st::historyComposeFieldMaxHeight - _field->height();
_keyboard->resizeToWidth(_chatWidth, maxKeyboardHeight); _keyboard->resizeToWidth(width(), maxKeyboardHeight);
if (_kbShown) { if (_kbShown) {
keyboardHeight = qMin(_keyboard->height(), maxKeyboardHeight); keyboardHeight = qMin(_keyboard->height(), maxKeyboardHeight);
bottom -= keyboardHeight; bottom -= keyboardHeight;
_kbScroll->setGeometryToLeft(0, bottom, _chatWidth, keyboardHeight); _kbScroll->setGeometryToLeft(0, bottom, width(), keyboardHeight);
} }
// _attachToggle --------- _inlineResults -------------------------------------- _tabbedPanel --------- _fieldBarCancel // _attachToggle --------- _inlineResults -------------------------------------- _tabbedPanel --------- _fieldBarCancel
@ -4121,7 +3938,7 @@ void HistoryWidget::moveFieldControls() {
auto left = 0; auto left = 0;
_attachToggle->moveToLeft(left, buttonsBottom); left += _attachToggle->width(); _attachToggle->moveToLeft(left, buttonsBottom); left += _attachToggle->width();
_field->moveToLeft(left, bottom - _field->height() - st::historySendPadding); _field->moveToLeft(left, bottom - _field->height() - st::historySendPadding);
auto right = (width() - _chatWidth) + st::historySendRight; auto right = st::historySendRight;
_send->moveToRight(right, buttonsBottom); right += _send->width(); _send->moveToRight(right, buttonsBottom); right += _send->width();
_tabbedSelectorToggle->moveToRight(right, buttonsBottom); _tabbedSelectorToggle->moveToRight(right, buttonsBottom);
updateTabbedSelectorToggleTooltipGeometry(); updateTabbedSelectorToggleTooltipGeometry();
@ -4130,7 +3947,7 @@ void HistoryWidget::moveFieldControls() {
_botCommandStart->moveToRight(right, buttonsBottom); _botCommandStart->moveToRight(right, buttonsBottom);
_silent->moveToRight(right, buttonsBottom); _silent->moveToRight(right, buttonsBottom);
_fieldBarCancel->moveToRight(width() - _chatWidth, _field->y() - st::historySendPadding - _fieldBarCancel->height()); _fieldBarCancel->moveToRight(0, _field->y() - st::historySendPadding - _fieldBarCancel->height());
if (_inlineResults) { if (_inlineResults) {
_inlineResults->moveBottom(_field->y() - st::historySendPadding); _inlineResults->moveBottom(_field->y() - st::historySendPadding);
} }
@ -4138,7 +3955,11 @@ void HistoryWidget::moveFieldControls() {
_tabbedPanel->moveBottom(buttonsBottom); _tabbedPanel->moveBottom(buttonsBottom);
} }
auto fullWidthButtonRect = myrtlrect(0, bottom - _botStart->height(), _chatWidth, _botStart->height()); auto fullWidthButtonRect = myrtlrect(
0,
bottom - _botStart->height(),
width(),
_botStart->height());
_botStart->setGeometry(fullWidthButtonRect); _botStart->setGeometry(fullWidthButtonRect);
_unblock->setGeometry(fullWidthButtonRect); _unblock->setGeometry(fullWidthButtonRect);
_joinChannel->setGeometry(fullWidthButtonRect); _joinChannel->setGeometry(fullWidthButtonRect);
@ -4156,7 +3977,7 @@ void HistoryWidget::updateTabbedSelectorToggleTooltipGeometry() {
void HistoryWidget::updateFieldSize() { void HistoryWidget::updateFieldSize() {
auto kbShowShown = _history && !_kbShown && _keyboard->hasMarkup(); auto kbShowShown = _history && !_kbShown && _keyboard->hasMarkup();
auto fieldWidth = _chatWidth - _attachToggle->width() - st::historySendRight; auto fieldWidth = width() - _attachToggle->width() - st::historySendRight;
fieldWidth -= _send->width(); fieldWidth -= _send->width();
fieldWidth -= _tabbedSelectorToggle->width(); fieldWidth -= _tabbedSelectorToggle->width();
if (kbShowShown) fieldWidth -= _botKeyboardShow->width(); if (kbShowShown) fieldWidth -= _botKeyboardShow->width();
@ -4780,31 +4601,28 @@ void HistoryWidget::handlePendingHistoryUpdate() {
} }
void HistoryWidget::resizeEvent(QResizeEvent *e) { void HistoryWidget::resizeEvent(QResizeEvent *e) {
updateTabbedSelectorSectionShown(); //updateTabbedSelectorSectionShown();
recountChatWidth(); recountChatWidth();
updateControlsGeometry(); updateControlsGeometry();
} }
void HistoryWidget::updateControlsGeometry() { void HistoryWidget::updateControlsGeometry() {
if (_tabbedSection) { _topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
_tabbedSection->setGeometryToRight(0, 0, st::emojiPanWidth, height());
}
_topBar->setGeometryToLeft(0, 0, _chatWidth, st::topBarHeight);
moveFieldControls(); moveFieldControls();
auto scrollAreaTop = _topBar->bottomNoMargins(); auto scrollAreaTop = _topBar->bottomNoMargins();
if (_pinnedBar) { if (_pinnedBar) {
_pinnedBar->cancel->moveToLeft(_chatWidth - _pinnedBar->cancel->width(), scrollAreaTop); _pinnedBar->cancel->moveToLeft(width() - _pinnedBar->cancel->width(), scrollAreaTop);
scrollAreaTop += st::historyReplyHeight; scrollAreaTop += st::historyReplyHeight;
_pinnedBar->shadow->setGeometryToLeft(0, scrollAreaTop, _chatWidth, st::lineWidth); _pinnedBar->shadow->setGeometryToLeft(0, scrollAreaTop, width(), st::lineWidth);
} }
if (_scroll->y() != scrollAreaTop) { if (_scroll->y() != scrollAreaTop) {
_scroll->moveToLeft(0, scrollAreaTop); _scroll->moveToLeft(0, scrollAreaTop);
_fieldAutocomplete->setBoundings(_scroll->geometry()); _fieldAutocomplete->setBoundings(_scroll->geometry());
} }
if (_reportSpamPanel) { if (_reportSpamPanel) {
_reportSpamPanel->setGeometryToLeft(0, _scroll->y(), _chatWidth, _reportSpamPanel->height()); _reportSpamPanel->setGeometryToLeft(0, _scroll->y(), width(), _reportSpamPanel->height());
} }
updateHistoryGeometry(false, false, { ScrollChangeAdd, App::main() ? App::main()->contentScrollAddToY() : 0 }); updateHistoryGeometry(false, false, { ScrollChangeAdd, App::main() ? App::main()->contentScrollAddToY() : 0 });
@ -4834,12 +4652,13 @@ void HistoryWidget::updateControlsGeometry() {
break; break;
} }
if (_rightShadow) {
_rightShadow->setGeometryToLeft(_chatWidth - st::lineWidth, 0, st::lineWidth, height());
}
auto topShadowLeft = (Adaptive::OneColumn() || _inGrab) ? 0 : st::lineWidth; auto topShadowLeft = (Adaptive::OneColumn() || _inGrab) ? 0 : st::lineWidth;
auto topShadowRight = _rightShadow ? st::lineWidth : 0; auto topShadowRight = (Adaptive::ThreeColumn() && !_inGrab && _peer) ? st::lineWidth : 0;
_topShadow->setGeometryToLeft(topShadowLeft, _topBar->bottomNoMargins(), _chatWidth - topShadowLeft - topShadowRight, st::lineWidth); _topShadow->setGeometryToLeft(
topShadowLeft,
_topBar->bottomNoMargins(),
width() - topShadowLeft - topShadowRight,
st::lineWidth);
} }
void HistoryWidget::itemRemoved(HistoryItem *item) { void HistoryWidget::itemRemoved(HistoryItem *item) {
@ -4963,9 +4782,9 @@ void HistoryWidget::updateHistoryGeometry(bool initial, bool loadedDown, const S
auto wasScrollTop = _scroll->scrollTop(); auto wasScrollTop = _scroll->scrollTop();
auto wasScrollTopMax = _scroll->scrollTopMax(); auto wasScrollTopMax = _scroll->scrollTopMax();
auto wasAtBottom = wasScrollTop + 1 > wasScrollTopMax; auto wasAtBottom = wasScrollTop + 1 > wasScrollTopMax;
auto needResize = (_scroll->width() != _chatWidth) || (_scroll->height() != newScrollHeight); auto needResize = (_scroll->width() != width()) || (_scroll->height() != newScrollHeight);
if (needResize) { if (needResize) {
_scroll->resize(_chatWidth, newScrollHeight); _scroll->resize(width(), newScrollHeight);
// on initial updateListSize we didn't put the _scroll->scrollTop correctly yet // on initial updateListSize we didn't put the _scroll->scrollTop correctly yet
// so visibleAreaUpdated() call will erase it with the new (undefined) value // so visibleAreaUpdated() call will erase it with the new (undefined) value
if (!initial) { if (!initial) {
@ -6379,7 +6198,7 @@ void HistoryWidget::updateReplyToName() {
void HistoryWidget::updateField() { void HistoryWidget::updateField() {
auto fieldAreaTop = _scroll->y() + _scroll->height(); auto fieldAreaTop = _scroll->y() + _scroll->height();
rtlupdate(0, fieldAreaTop, _chatWidth, height() - fieldAreaTop); rtlupdate(0, fieldAreaTop, width(), height() - fieldAreaTop);
} }
void HistoryWidget::drawField(Painter &p, const QRect &rect) { void HistoryWidget::drawField(Painter &p, const QRect &rect) {
@ -6402,7 +6221,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
backh += st::historyReplyHeight; backh += st::historyReplyHeight;
} }
auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed; auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
p.fillRect(myrtlrect(0, backy, _chatWidth, backh), st::historyReplyBg); p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) { if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
auto replyLeft = st::historyReplySkip; auto replyLeft = st::historyReplySkip;
(_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); (_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width());
@ -6420,14 +6239,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (_editMsgId) { if (_editMsgId) {
paintEditHeader(p, rect, replyLeft, backy); paintEditHeader(p, rect, replyLeft, backy);
} else { } else {
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
} }
p.setPen(((drawMsgText->toHistoryMessage() && drawMsgText->toHistoryMessage()->emptyText()) || drawMsgText->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg); p.setPen(((drawMsgText->toHistoryMessage() && drawMsgText->toHistoryMessage()->emptyText()) || drawMsgText->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
_replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
} else { } else {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);
p.setPen(st::historyComposeAreaFgService); p.setPen(st::historyComposeAreaFgService);
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right())); p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
} }
} }
} else if (hasForward) { } else if (hasForward) {
@ -6451,7 +6270,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
p.setPen(st::historyReplyNameFg); p.setPen(st::historyReplyNameFg);
_toForwardFrom.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _toForwardFrom.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
p.setPen(serviceColor ? st::historyComposeAreaFgService : st::historyComposeAreaFg); p.setPen(serviceColor ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
_toForwardText.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _toForwardText.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
} }
} }
if (drawWebPagePreview) { if (drawWebPagePreview) {
@ -6471,14 +6290,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
p.setPen(st::historyReplyNameFg); p.setPen(st::historyReplyNameFg);
_previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), _chatWidth - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), width() - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
p.setPen(st::historyComposeAreaFg); p.setPen(st::historyComposeAreaFg);
_previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
} }
} }
void HistoryWidget::drawRestrictedWrite(Painter &p) { void HistoryWidget::drawRestrictedWrite(Painter &p) {
auto rect = myrtlrect(0, height() - _unblock->height(), _chatWidth, _unblock->height()); auto rect = myrtlrect(0, height() - _unblock->height(), width(), _unblock->height());
p.fillRect(rect, st::historyReplyBg); p.fillRect(rect, st::historyReplyBg);
p.setFont(st::normalFont); p.setFont(st::normalFont);
@ -6487,7 +6306,7 @@ void HistoryWidget::drawRestrictedWrite(Painter &p) {
} }
void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const { void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const {
if (!rect.intersects(myrtlrect(left, top, _chatWidth - left, st::normalFont->height))) { if (!rect.intersects(myrtlrect(left, top, width() - left, st::normalFont->height))) {
return; return;
} }
@ -6517,7 +6336,7 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
} }
// Restart timer only if we are sure that we've painted the whole timer. // Restart timer only if we are sure that we've painted the whole timer.
if (rect.contains(myrtlrect(left, top, _chatWidth - left, st::normalFont->height)) && updateIn > 0) { if (rect.contains(myrtlrect(left, top, width() - left, st::normalFont->height)) && updateIn > 0) {
_updateEditTimeLeftDisplay.start(updateIn); _updateEditTimeLeftDisplay.start(updateIn);
} }
@ -6546,7 +6365,7 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
p.drawText(_attachToggle->x() + _tabbedSelectorToggle->width(), _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, duration); p.drawText(_attachToggle->x() + _tabbedSelectorToggle->width(), _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, duration);
int32 left = _attachToggle->x() + _tabbedSelectorToggle->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2); int32 left = _attachToggle->x() + _tabbedSelectorToggle->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2);
int32 right = _chatWidth - _send->width(); int32 right = width() - _send->width();
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive)); p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, lang(lng_record_cancel)); p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, lang(lng_record_cancel));
@ -6559,7 +6378,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
Text *from = 0, *text = 0; Text *from = 0, *text = 0;
bool serviceColor = false, hasForward = readyToForward(); bool serviceColor = false, hasForward = readyToForward();
ImagePtr preview; ImagePtr preview;
p.fillRect(myrtlrect(0, top, _chatWidth, st::historyReplyHeight), st::historyPinnedBg); p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
top += st::msgReplyPadding.top(); top += st::msgReplyPadding.top();
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height())); QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
@ -6580,11 +6399,11 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message)); p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message));
p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg); p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
_pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, _chatWidth - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()); _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
} else { } else {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);
p.setPen(st::historyComposeAreaFgService); p.setPen(st::historyComposeAreaFgService);
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), _chatWidth - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right())); p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
} }
} }
@ -6607,7 +6426,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
_unreadMentionsShown.step(ms); _unreadMentionsShown.step(ms);
auto progress = _a_show.current(ms, 1.); auto progress = _a_show.current(ms, 1.);
if (_a_show.animating()) { if (_a_show.animating()) {
auto animationWidth = (!_tabbedSection || _tabbedSection->isHidden()) ? width() : _chatWidth; auto animationWidth = width();
auto retina = cIntRetinaFactor(); auto retina = cIntRetinaFactor();
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft); auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress); auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
@ -6625,7 +6444,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
return; return;
} }
QRect fill(0, 0, _history ? _chatWidth : width(), App::main()->height()); QRect fill(0, 0, width(), App::main()->height());
auto fromy = App::main()->backgroundFromY(); auto fromy = App::main()->backgroundFromY();
auto x = 0, y = 0; auto x = 0, y = 0;
QPixmap cached = App::main()->cachedBackground(fill, x, y); QPixmap cached = App::main()->cachedBackground(fill, x, y);

View File

@ -207,15 +207,13 @@ public:
void unreadCountChanged(History *history); void unreadCountChanged(History *history);
QRect historyRect() const; QRect historyRect() const;
int tabbedSelectorSectionWidth() const; void pushTabbedSelectorToThirdSection();
int minimalWidthForTabbedSelectorSection() const; void pushInfoToThirdSection();
bool willSwitchToTabbedSelectorWithWidth(int newWidth) const;
void updateSendAction(History *history, SendAction::Type type, int32 progress = 0); void updateSendAction(History *history, SendAction::Type type, int32 progress = 0);
void cancelSendAction(History *history, SendAction::Type type); void cancelSendAction(History *history, SendAction::Type type);
void updateRecentStickers(); void updateRecentStickers();
void stickersInstalled(uint64 setId);
void sendActionDone(const MTPBool &result, mtpRequestId req); void sendActionDone(const MTPBool &result, mtpRequestId req);
void destroyData(); void destroyData();
@ -347,8 +345,8 @@ public:
void deleteSelectedItems(bool forEveryone); void deleteSelectedItems(bool forEveryone);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, not_null<const HistoryItem*> msg, int row, int col); void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, not_null<const HistoryItem*> msg, int row, int col);
@ -479,12 +477,14 @@ private:
QStringList filesToSend; QStringList filesToSend;
bool allFilesForCompress = true; bool allFilesForCompress = true;
}; };
using TabbedPanel = ChatHelpers::TabbedPanel;
using TabbedSelector = ChatHelpers::TabbedSelector;
void handlePendingHistoryUpdate(); void handlePendingHistoryUpdate();
void fullPeerUpdated(PeerData *peer); void fullPeerUpdated(PeerData *peer);
void topBarClick(); void topBarClick();
void toggleTabbedSelectorMode(); void toggleTabbedSelectorMode();
void updateTabbedSelectorSectionShown(); void returnTabbedSelector(object_ptr<TabbedSelector> selector);
void recountChatWidth(); void recountChatWidth();
void setReportSpamStatus(DBIPeerReportSpamStatus status); void setReportSpamStatus(DBIPeerReportSpamStatus status);
void historyDownClicked(); void historyDownClicked();
@ -562,7 +562,6 @@ private:
int _toForwardNameVersion = 0; int _toForwardNameVersion = 0;
int _forwardingItemRemovedSubscription = 0; int _forwardingItemRemovedSubscription = 0;
int _chatWidth = 0;
MsgId _editMsgId = 0; MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg = nullptr; HistoryItem *_replyEditMsg = nullptr;
@ -822,10 +821,8 @@ private:
QTimer _membersDropdownShowTimer; QTimer _membersDropdownShowTimer;
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr }; object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
object_ptr<ChatHelpers::TabbedPanel> _tabbedPanel; object_ptr<TabbedPanel> _tabbedPanel;
object_ptr<ChatHelpers::TabbedSection> _tabbedSection = { nullptr }; QPointer<TabbedSelector> _tabbedSelector;
QPointer<ChatHelpers::TabbedSelector> _tabbedSelector;
bool _tabbedSectionUsed = false;
DragState _attachDrag = DragStateNone; DragState _attachDrag = DragStateNone;
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto; object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
@ -863,7 +860,6 @@ private:
QTimer _saveDraftTimer, _saveCloudDraftTimer; QTimer _saveDraftTimer, _saveCloudDraftTimer;
object_ptr<Ui::PlainShadow> _topShadow; object_ptr<Ui::PlainShadow> _topShadow;
object_ptr<Ui::PlainShadow> _rightShadow = { nullptr };
bool _inGrab = false; bool _inGrab = false;
}; };

View File

@ -106,7 +106,7 @@ void LayerWrap::parentResized() {
hide(); hide();
setParent(nullptr); setParent(nullptr);
auto localCopy = _controller; auto localCopy = _controller;
localCopy->showWideSection( localCopy->showSection(
MoveMemento(std::move(_content), Wrap::Narrow)); MoveMemento(std::move(_content), Wrap::Narrow));
localCopy->hideSpecialLayer(LayerOption::ForceFast); localCopy->hideSpecialLayer(LayerOption::ForceFast);
} else { } else {

View File

@ -30,14 +30,6 @@ InnerWidget::InnerWidget(
: RpWidget(parent) : RpWidget(parent)
, _peer(peer) , _peer(peer)
, _type(type) { , _type(type) {
base::lambda<void(int)> launch = [this, &launch](int counter) {
QTimer::singleShot(500, this, [this, launch, counter] {
_rowsHeightFake += 300;
resizeToWidth(width(), _minHeight);
launch(counter - 1);
});
};
launch(10);
} }
void InnerWidget::visibleTopBottomUpdated( void InnerWidget::visibleTopBottomUpdated(

View File

@ -165,7 +165,14 @@ std::unique_ptr<ContentMemento> Memento::Default(
object_ptr<Window::SectionWidget> Memento::createWidget( object_ptr<Window::SectionWidget> Memento::createWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) { const QRect &geometry) {
if (column == Window::Column::Third) {
return object_ptr<SideWrap>(
parent,
controller,
this);
}
return object_ptr<NarrowWrap>( return object_ptr<NarrowWrap>(
parent, parent,
controller, controller,
@ -193,21 +200,24 @@ MoveMemento::MoveMemento(
object_ptr<Window::SectionWidget> MoveMemento::createWidget( object_ptr<Window::SectionWidget> MoveMemento::createWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) { const QRect &geometry) {
if (_wrap == Wrap::Narrow) { if (_wrap == Wrap::Narrow && column != Window::Column::Third) {
auto result = object_ptr<NarrowWrap>( auto result = object_ptr<NarrowWrap>(
parent, parent,
controller, controller,
this); this);
result->setGeometry(geometry); result->setGeometry(geometry);
return result; return result;
} else if (_wrap == Wrap::Side && column == Window::Column::Third) {
auto result = object_ptr<SideWrap>(
parent,
controller,
this);
result->setGeometry(geometry);
return result;
} }
auto result = object_ptr<SideWrap>( return nullptr;
parent,
controller,
this);
result->setGeometry(geometry);
return result;
} }
object_ptr<LayerWidget> MoveMemento::createLayer( object_ptr<LayerWidget> MoveMemento::createLayer(

View File

@ -195,6 +195,7 @@ public:
object_ptr<Window::SectionWidget> createWidget( object_ptr<Window::SectionWidget> createWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override; const QRect &geometry) override;
object_ptr<LayerWidget> createLayer( object_ptr<LayerWidget> createLayer(
@ -232,6 +233,7 @@ public:
object_ptr<Window::SectionWidget> createWidget( object_ptr<Window::SectionWidget> createWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override; const QRect &geometry) override;
object_ptr<LayerWidget> createLayer( object_ptr<LayerWidget> createLayer(

View File

@ -176,20 +176,20 @@ void NarrowWrap::resizeEvent(QResizeEvent *e) {
} }
void NarrowWrap::paintEvent(QPaintEvent *e) { void NarrowWrap::paintEvent(QPaintEvent *e) {
SectionWidget::paintEvent(e);
if (animating()) {
return;
}
Painter p(this); Painter p(this);
p.fillRect(e->rect(), st::profileBg); p.fillRect(e->rect(), st::profileBg);
} }
bool NarrowWrap::wheelEventFromFloatPlayer( bool NarrowWrap::wheelEventFromFloatPlayer(QEvent *e) {
QEvent *e,
Window::Column myColumn,
Window::Column playerColumn) {
return _content->wheelEventFromFloatPlayer(e); return _content->wheelEventFromFloatPlayer(e);
} }
QRect NarrowWrap::rectForFloatPlayer( QRect NarrowWrap::rectForFloatPlayer() const {
Window::Column myColumn,
Window::Column playerColumn) const {
return _content->rectForFloatPlayer(); return _content->rectForFloatPlayer();
} }

View File

@ -79,13 +79,8 @@ public:
not_null<Memento*> memento); not_null<Memento*> memento);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer( bool wheelEventFromFloatPlayer(QEvent *e) override;
QEvent *e, QRect rectForFloatPlayer() const override;
Window::Column myColumn,
Window::Column playerColumn) override;
QRect rectForFloatPlayer(
Window::Column myColumn,
Window::Column playerColumn) const override;
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;

View File

@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "info/info_media_widget.h" #include "info/info_media_widget.h"
#include "info/info_memento.h" #include "info/info_memento.h"
#include "ui/widgets/discrete_sliders.h" #include "ui/widgets/discrete_sliders.h"
#include "auth_session.h"
#include "ui/widgets/shadow.h" #include "ui/widgets/shadow.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "styles/style_info.h" #include "styles/style_info.h"
@ -80,8 +81,7 @@ void SideWrap::showTab(Tab tab) {
showContent(createContent(tab)); showContent(createContent(tab));
} }
void SideWrap::showContent(object_ptr<ContentWidget> content) { void SideWrap::setSection(const Section &section) {
auto section = content->section();
switch (section.type()) { switch (section.type()) {
case Section::Type::Profile: case Section::Type::Profile:
setCurrentTab(Tab::Profile); setCurrentTab(Tab::Profile);
@ -102,7 +102,9 @@ void SideWrap::showContent(object_ptr<ContentWidget> content) {
setCurrentTab(Tab::None); setCurrentTab(Tab::None);
break; break;
} }
}
void SideWrap::showContent(object_ptr<ContentWidget> content) {
_content = std::move(content); _content = std::move(content);
_content->setGeometry(contentGeometry()); _content->setGeometry(contentGeometry());
_content->show(); _content->show();
@ -158,6 +160,9 @@ void SideWrap::doSetInnerFocus() {
_content->setInnerFocus(); _content->setInnerFocus();
} }
void SideWrap::showFinishedHook() {
}
bool SideWrap::showInternal( bool SideWrap::showInternal(
not_null<Window::SectionMemento*> memento) { not_null<Window::SectionMemento*> memento) {
if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) { if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) {
@ -203,6 +208,8 @@ QRect SideWrap::contentGeometry() const {
} }
void SideWrap::restoreState(not_null<Memento*> memento) { void SideWrap::restoreState(not_null<Memento*> memento) {
// Validates contentGeometry().
setSection(memento->section());
showContent(memento->content()->createWidget( showContent(memento->content()->createWidget(
this, this,
Wrap::Side, Wrap::Side,
@ -211,7 +218,9 @@ void SideWrap::restoreState(not_null<Memento*> memento) {
} }
void SideWrap::restoreState(not_null<MoveMemento*> memento) { void SideWrap::restoreState(not_null<MoveMemento*> memento) {
showContent(memento->content(this, Wrap::Side)); auto content = memento->content(this, Wrap::Side);
setSection(content->section());
showContent(std::move(content));
} }
void SideWrap::setCurrentTab(Tab tab) { void SideWrap::setCurrentTab(Tab tab) {
@ -235,20 +244,20 @@ void SideWrap::resizeEvent(QResizeEvent *e) {
} }
void SideWrap::paintEvent(QPaintEvent *e) { void SideWrap::paintEvent(QPaintEvent *e) {
SectionWidget::paintEvent(e);
if (animating()) {
return;
}
Painter p(this); Painter p(this);
p.fillRect(e->rect(), st::profileBg); p.fillRect(e->rect(), st::profileBg);
} }
bool SideWrap::wheelEventFromFloatPlayer( bool SideWrap::wheelEventFromFloatPlayer(QEvent *e) {
QEvent *e,
Window::Column myColumn,
Window::Column playerColumn) {
return _content->wheelEventFromFloatPlayer(e); return _content->wheelEventFromFloatPlayer(e);
} }
QRect SideWrap::rectForFloatPlayer( QRect SideWrap::rectForFloatPlayer() const {
Window::Column myColumn,
Window::Column playerColumn) const {
return _content->rectForFloatPlayer(); return _content->rectForFloatPlayer();
} }

View File

@ -37,6 +37,7 @@ namespace Media {
class Widget; class Widget;
} // namespace Media } // namespace Media
class Section;
class Memento; class Memento;
class MoveMemento; class MoveMemento;
class ContentWidget; class ContentWidget;
@ -75,19 +76,15 @@ public:
not_null<Memento*> memento); not_null<Memento*> memento);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer( bool wheelEventFromFloatPlayer(QEvent *e) override;
QEvent *e, QRect rectForFloatPlayer() const override;
Window::Column myColumn,
Window::Column playerColumn) override;
QRect rectForFloatPlayer(
Window::Column myColumn,
Window::Column playerColumn) const override;
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
void doSetInnerFocus() override; void doSetInnerFocus() override;
void showFinishedHook() override;
private: private:
enum class Tab { enum class Tab {
@ -105,6 +102,7 @@ private:
void setupTabs(); void setupTabs();
void showTab(Tab tab); void showTab(Tab tab);
void setCurrentTab(Tab tab); void setCurrentTab(Tab tab);
void setSection(const Section &section);
void showContent(object_ptr<ContentWidget> content); void showContent(object_ptr<ContentWidget> content);
object_ptr<ContentWidget> createContent(Tab tab); object_ptr<ContentWidget> createContent(Tab tab);
object_ptr<Profile::Widget> createProfileWidget(); object_ptr<Profile::Widget> createProfileWidget();

File diff suppressed because it is too large Load Diff

View File

@ -156,7 +156,8 @@ class MainWidget : public Ui::RpWidget, public RPCSender, private base::Subscrib
public: public:
MainWidget(QWidget *parent, not_null<Window::Controller*> controller); MainWidget(QWidget *parent, not_null<Window::Controller*> controller);
bool isSectionShown() const; bool isMainSectionShown() const;
bool isThirdSectionShown() const;
// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget. // Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms); bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms);
@ -212,14 +213,17 @@ public:
int backgroundFromY() const; int backgroundFromY() const;
PeerData *overviewPeer(); PeerData *overviewPeer();
bool showMediaTypeSwitch() const; bool showMediaTypeSwitch() const;
void showWideSection(Window::SectionMemento &&memento); void showSection(
Window::SectionMemento &&memento,
anim::type animated);
void updateColumnLayout();
void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1); void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
bool stackIsEmpty() const; bool stackIsEmpty() const;
void showBackFromStack(); void showBackFromStack();
void orderWidgets(); void orderWidgets();
QRect historyRect() const; QRect historyRect() const;
QPixmap grabForShowAnimation(const Window::SectionSlideParams &params); QPixmap grabForShowAnimation(const Window::SectionSlideParams &params);
void checkWideSectionToLayer(); void checkMainSectionToLayer();
void onSendFileConfirm(const FileLoadResultPtr &file); void onSendFileConfirm(const FileLoadResultPtr &file);
bool onSendSticker(DocumentData *sticker); bool onSendSticker(DocumentData *sticker);
@ -442,8 +446,6 @@ public slots:
void onUpdateMuted(); void onUpdateMuted();
void onStickersInstalled(uint64 setId);
void onViewsIncrement(); void onViewsIncrement();
void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way); void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way);
@ -523,12 +525,19 @@ private:
mtpRequestId req); mtpRequestId req);
void mediaOverviewUpdated(const Notify::PeerUpdate &update); void mediaOverviewUpdated(const Notify::PeerUpdate &update);
Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection); Window::SectionSlideParams prepareShowAnimation(
void showNewWideSection(Window::SectionMemento &&memento, bool back, bool saveInStack); bool willHaveTopBarShadow);
void dropWideSection(Window::SectionWidget *widget); void showNewSection(
Window::SectionMemento &&memento,
bool back,
bool saveInStack,
anim::type animated);
void dropMainSection(Window::SectionWidget *widget);
Window::SectionSlideParams prepareThirdSectionAnimation(Window::SectionWidget *section);
// All this methods use the prepareShowAnimation(). // All this methods use the prepareShowAnimation().
Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section); Window::SectionSlideParams prepareMainSectionAnimation(Window::SectionWidget *section);
Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId); Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId);
Window::SectionSlideParams prepareOverviewAnimation(); Window::SectionSlideParams prepareOverviewAnimation();
Window::SectionSlideParams prepareDialogsAnimation(); Window::SectionSlideParams prepareDialogsAnimation();
@ -564,7 +573,8 @@ private:
void inviteImportDone(const MTPUpdates &result); void inviteImportDone(const MTPUpdates &result);
bool inviteImportFail(const RPCError &error); bool inviteImportFail(const RPCError &error);
int getSectionTop() const; int getMainSectionTop() const;
int getThirdSectionTop() const;
void hideAll(); void hideAll();
void showAll(); void showAll();
@ -581,11 +591,17 @@ private:
Float *currentFloatPlayer() const { Float *currentFloatPlayer() const {
return _playerFloats.empty() ? nullptr : _playerFloats.back().get(); return _playerFloats.empty() ? nullptr : _playerFloats.back().get();
} }
Window::AbstractSectionWidget *getFloatPlayerSection(not_null<Window::Column*> column) const; Window::AbstractSectionWidget *getFloatPlayerSection(
void finishFloatPlayerDrag(not_null<Float*> instance, bool closed); Window::Column column) const;
void finishFloatPlayerDrag(
not_null<Float*> instance,
bool closed);
void updateFloatPlayerColumnCorner(QPoint center); void updateFloatPlayerColumnCorner(QPoint center);
QPoint getFloatPlayerPosition(not_null<Float*> instance) const; QPoint getFloatPlayerPosition(not_null<Float*> instance) const;
QPoint getFloatPlayerHiddenPosition(QPoint position, QSize size, RectPart side) const; QPoint getFloatPlayerHiddenPosition(
QPoint position,
QSize size,
RectPart side) const;
RectPart getFloatPlayerSide(QPoint center) const; RectPart getFloatPlayerSide(QPoint center) const;
bool ptsUpdateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates); bool ptsUpdateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
@ -615,10 +631,11 @@ private:
Animation _a_dialogsWidth; Animation _a_dialogsWidth;
object_ptr<Ui::PlainShadow> _sideShadow; object_ptr<Ui::PlainShadow> _sideShadow;
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
object_ptr<TWidget> _sideResizeArea; object_ptr<TWidget> _sideResizeArea;
object_ptr<DialogsWidget> _dialogs; object_ptr<DialogsWidget> _dialogs;
object_ptr<HistoryWidget> _history; object_ptr<HistoryWidget> _history;
object_ptr<Window::SectionWidget> _wideSection = { nullptr }; object_ptr<Window::SectionWidget> _mainSection = { nullptr };
object_ptr<Window::SectionWidget> _thirdSection = { nullptr }; object_ptr<Window::SectionWidget> _thirdSection = { nullptr };
object_ptr<OverviewWidget> _overview = { nullptr }; object_ptr<OverviewWidget> _overview = { nullptr };

View File

@ -812,7 +812,7 @@ void MainWindow::updateControlsGeometry() {
if (_connecting) _connecting->moveToLeft(0, body.height() - _connecting->height()); if (_connecting) _connecting->moveToLeft(0, body.height() - _connecting->height());
if (_testingThemeWarning) _testingThemeWarning->setGeometry(body); if (_testingThemeWarning) _testingThemeWarning->setGeometry(body);
if (_main) _main->checkWideSectionToLayer(); if (_main) _main->checkMainSectionToLayer();
} }
MainWindow::TempDirState MainWindow::tempDirState() { MainWindow::TempDirState MainWindow::tempDirState() {

View File

@ -62,7 +62,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P
, _search(this, st::overviewFilter, langFactory(lng_dlg_filter)) , _search(this, st::overviewFilter, langFactory(lng_dlg_filter))
, _cancelSearch(this, st::dialogsCancelSearch) , _cancelSearch(this, st::dialogsCancelSearch)
, _itemsToBeLoaded(LinksOverviewPerPage * 2) , _itemsToBeLoaded(LinksOverviewPerPage * 2)
, _width(st::windowMinWidth) { , _width(st::columnMinimalWidthMain) {
subscribe(Auth().downloader().taskFinished(), [this] { update(); }); subscribe(Auth().downloader().taskFinished(), [this] { update(); });
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) { subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
itemRemoved(item); itemRemoved(item);
@ -1314,7 +1314,7 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
contentLeftMin -= st::overviewFileLayout.songPadding.left(); contentLeftMin -= st::overviewFileLayout.songPadding.left();
contentLeftMax -= st::overviewFileLayout.songPadding.left(); contentLeftMax -= st::overviewFileLayout.songPadding.left();
} }
auto widthWithMin = st::windowMinWidth; auto widthWithMin = st::columnMinimalWidthMain;
auto widthWithMax = st::overviewFileLayout.maxWidth + 2 * contentLeftMax; auto widthWithMax = st::overviewFileLayout.maxWidth + 2 * contentLeftMax;
_rowsLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - _width, 0) / float64(widthWithMax - widthWithMin)); _rowsLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - _width, 0) / float64(widthWithMax - widthWithMin));
_rowWidth = qMin(_width - 2 * _rowsLeft, st::overviewFileLayout.maxWidth); _rowWidth = qMin(_width - 2 * _rowsLeft, st::overviewFileLayout.maxWidth);
@ -2145,11 +2145,11 @@ int32 OverviewWidget::lastScrollTop() const {
return _scroll->scrollTop(); return _scroll->scrollTop();
} }
bool OverviewWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool OverviewWidget::wheelEventFromFloatPlayer(QEvent *e) {
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect OverviewWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect OverviewWidget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }

View File

@ -349,8 +349,8 @@ public:
void deleteSelectedItems(bool forEveryone); void deleteSelectedItems(bool forEveryone);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
void ui_repaintHistoryItem(not_null<const HistoryItem*> item); void ui_repaintHistoryItem(not_null<const HistoryItem*> item);

View File

@ -156,7 +156,7 @@ void ChannelMembersWidget::onAdmins() {
void ChannelMembersWidget::onRecentActions() { void ChannelMembersWidget::onRecentActions() {
if (auto channel = peer()->asChannel()) { if (auto channel = peer()->asChannel()) {
if (auto main = App::main()) { if (auto main = App::main()) {
main->showWideSection(AdminLog::SectionMemento(channel)); main->showSection(AdminLog::SectionMemento(channel), anim::type::normal);
} }
} }
} }

View File

@ -219,7 +219,7 @@ void SettingsWidget::onManageAdmins() {
void SettingsWidget::onRecentActions() { void SettingsWidget::onRecentActions() {
if (auto channel = peer()->asChannel()) { if (auto channel = peer()->asChannel()) {
if (auto main = App::main()) { if (auto main = App::main()) {
main->showWideSection(AdminLog::SectionMemento(channel)); main->showSection(AdminLog::SectionMemento(channel), anim::type::normal);
} }
} }
} }

View File

@ -201,7 +201,7 @@ void SharedMediaWidget::onShowCommonGroups() {
return; return;
} }
if (auto main = App::main()) { if (auto main = App::main()) {
main->showWideSection(Profile::CommonGroups::SectionMemento(peer()->asUser())); main->showSection(Profile::CommonGroups::SectionMemento(peer()->asUser()), anim::type::normal);
} }
} }

View File

@ -42,7 +42,11 @@ constexpr int kCommonGroupsPerPage = 40;
} // namespace } // namespace
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) { object_ptr<Window::SectionWidget> SectionMemento::createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) {
auto result = object_ptr<Widget>(parent, controller, _user); auto result = object_ptr<Widget>(parent, controller, _user);
result->setInternalState(geometry, this); result->setInternalState(geometry, this);
return std::move(result); return std::move(result);
@ -196,7 +200,7 @@ int InnerWidget::resizeGetHeight(int newWidth) {
auto contentLeftMin = st::profileCommonGroupsLeftMin; auto contentLeftMin = st::profileCommonGroupsLeftMin;
auto contentLeftMax = st::profileCommonGroupsLeftMax; auto contentLeftMax = st::profileCommonGroupsLeftMax;
auto widthWithMin = st::windowMinWidth; auto widthWithMin = st::columnMinimalWidthMain;
auto widthWithMax = st::profileCommonGroupsWidthMax + 2 * contentLeftMax; auto widthWithMax = st::profileCommonGroupsWidthMax + 2 * contentLeftMax;
_contentLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - newWidth, 0) / float64(widthWithMax - widthWithMin)); _contentLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - newWidth, 0) / float64(widthWithMax - widthWithMin));
_contentWidth = qMin(newWidth - 2 * _contentLeft, st::profileCommonGroupsWidthMax); _contentWidth = qMin(newWidth - 2 * _contentLeft, st::profileCommonGroupsWidthMax);
@ -447,11 +451,11 @@ void Widget::showFinishedHook() {
_fixedBar->setAnimatingMode(false); _fixedBar->setAnimatingMode(false);
} }
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect Widget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }

View File

@ -43,7 +43,11 @@ public:
SectionMemento(not_null<UserData*> user) : _user(user) { SectionMemento(not_null<UserData*> user) : _user(user) {
} }
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override; object_ptr<Window::SectionWidget> createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override;
not_null<UserData*> getUser() const { not_null<UserData*> getUser() const {
return _user; return _user;
@ -189,8 +193,8 @@ public:
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento); void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;

View File

@ -117,7 +117,7 @@ void CoverWidget::onCancelPhotoUpload() {
int CoverWidget::countPhotoLeft(int newWidth) const { int CoverWidget::countPhotoLeft(int newWidth) const {
int result = st::profilePhotoLeftMin; int result = st::profilePhotoLeftMin;
result += (newWidth - st::windowMinWidth) / 2; result += (newWidth - st::columnMinimalWidthMain) / 2;
return qMin(result, st::profilePhotoLeftMax); return qMin(result, st::profilePhotoLeftMax);
} }

View File

@ -148,7 +148,7 @@ int InnerWidget::countBlocksHeight(RectPart countSide) const {
int InnerWidget::countBlocksLeft(int newWidth) const { int InnerWidget::countBlocksLeft(int newWidth) const {
int result = st::profileBlockLeftMin; int result = st::profileBlockLeftMin;
result += (newWidth - st::windowMinWidth) / 2; result += (newWidth - st::columnMinimalWidthMain) / 2;
return qMin(result, st::profileBlockLeftMax); return qMin(result, st::profileBlockLeftMax);
} }

View File

@ -24,7 +24,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace Profile { namespace Profile {
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) { object_ptr<Window::SectionWidget> SectionMemento::createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) {
auto result = object_ptr<Widget>(parent, controller, _peer); auto result = object_ptr<Widget>(parent, controller, _peer);
result->setInternalState(geometry, this); result->setInternalState(geometry, this);
return std::move(result); return std::move(result);

View File

@ -31,7 +31,11 @@ public:
SectionMemento(PeerData *peer) : _peer(peer) { SectionMemento(PeerData *peer) : _peer(peer) {
} }
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override; object_ptr<Window::SectionWidget> createWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
Window::Column column,
const QRect &geometry) override;
PeerData *getPeer() const { PeerData *getPeer() const {
return _peer; return _peer;

View File

@ -161,11 +161,11 @@ void Widget::showFinishedHook() {
_inner->showFinished(); _inner->showFinished();
} }
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
return _scroll->viewportEvent(e); return _scroll->viewportEvent(e);
} }
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { QRect Widget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }

View File

@ -55,8 +55,8 @@ public:
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento); void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
// Float player interface. // Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override; QRect rectForFloatPlayer() const override;
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;

View File

@ -93,6 +93,11 @@ enum Notification {
namespace anim { namespace anim {
enum class type {
normal,
instant,
};
using transition = base::lambda<float64(float64 delta, float64 dt)>; using transition = base::lambda<float64(float64 delta, float64 dt)>;
extern transition linear; extern transition linear;

View File

@ -191,8 +191,6 @@ QPixmap myGrab(TWidget *target, QRect rect, QColor bg) {
result.fill(bg); result.fill(bg);
} }
App::wnd()->widgetGrabbed().notify(true);
target->grabStart(); target->grabStart();
target->render(&result, QPoint(0, 0), rect, QWidget::DrawChildren | QWidget::IgnoreMask); target->render(&result, QPoint(0, 0), rect, QWidget::DrawChildren | QWidget::IgnoreMask);
target->grabFinish(); target->grabFinish();

View File

@ -92,9 +92,6 @@ public:
base::Observable<void> &dragFinished() { base::Observable<void> &dragFinished() {
return _dragFinished; return _dragFinished;
} }
base::Observable<void> &widgetGrabbed() {
return _widgetGrabbed;
}
public slots: public slots:
bool minimizeToTray(); bool minimizeToTray();
@ -184,8 +181,7 @@ private:
base::Timer _inactivePressTimer; base::Timer _inactivePressTimer;
base::Observable<void> _dragFinished; base::Observable<void> _dragFinished;
base::Observable<void> _widgetGrabbed;
}; };
} // namespace Window } // namespace Window

View File

@ -26,12 +26,14 @@ namespace Window {
class Controller; class Controller;
class SectionWidget; class SectionWidget;
enum class Column;
class SectionMemento { class SectionMemento {
public: public:
virtual object_ptr<Window::SectionWidget> createWidget( virtual object_ptr<Window::SectionWidget> createWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
Column column,
const QRect &geometry) = 0; const QRect &geometry) = 0;
virtual object_ptr<LayerWidget> createLayer( virtual object_ptr<LayerWidget> createLayer(

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "window/section_widget.h" #include "window/section_widget.h"
#include "application.h" #include "application.h"
#include "window/section_memento.h"
#include <rpl/single.h> #include <rpl/single.h>
namespace Window { namespace Window {
@ -28,7 +29,7 @@ namespace Window {
SectionWidget::SectionWidget( SectionWidget::SectionWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller) not_null<Window::Controller*> controller)
: AbstractSectionWidget(parent, controller) { : AbstractSectionWidget(parent, controller) {
} }
void SectionWidget::setGeometryWithTopMoved( void SectionWidget::setGeometryWithTopMoved(
@ -72,6 +73,10 @@ void SectionWidget::showAnimated(
show(); show();
} }
std::unique_ptr<SectionMemento> SectionWidget::createMemento() {
return nullptr;
}
void SectionWidget::showFast() { void SectionWidget::showFast() {
show(); show();
showFinished(); showFinished();

View File

@ -45,10 +45,10 @@ public:
} }
// Float player interface. // Float player interface.
virtual bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) { virtual bool wheelEventFromFloatPlayer(QEvent *e) {
return false; return false;
} }
virtual QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const { virtual QRect rectForFloatPlayer() const {
return mapToGlobal(rect()); return mapToGlobal(rect());
} }
@ -67,7 +67,6 @@ class SectionMemento;
struct SectionSlideParams { struct SectionSlideParams {
QPixmap oldContentCache; QPixmap oldContentCache;
bool withTopBarShadow = false; bool withTopBarShadow = false;
bool withTabbedSection = false;
explicit operator bool() const { explicit operator bool() const {
return !oldContentCache.isNull(); return !oldContentCache.isNull();
@ -90,6 +89,9 @@ public:
virtual bool hasTopBarShadow() const { virtual bool hasTopBarShadow() const {
return false; return false;
} }
virtual bool forceAnimateBack() const {
return false;
}
void showAnimated(SlideDirection direction, const SectionSlideParams &params); void showAnimated(SlideDirection direction, const SectionSlideParams &params);
void showFast(); void showFast();
@ -109,7 +111,7 @@ public:
// Create a memento of that section to store it in the history stack. // Create a memento of that section to store it in the history stack.
// This method may modify the section ("take" heavy items). // This method may modify the section ("take" heavy items).
virtual std::unique_ptr<SectionMemento> createMemento() = 0; virtual std::unique_ptr<SectionMemento> createMemento();
void setInnerFocus() { void setInnerFocus() {
doSetInnerFocus(); doSetInnerFocus();

View File

@ -23,9 +23,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_window.h" #include "styles/style_window.h"
#include "boxes/add_contact_box.h" #include "boxes/add_contact_box.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "info/info_memento.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "auth_session.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/special_buttons.h" #include "ui/special_buttons.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
@ -36,8 +38,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "observer_peer.h" #include "observer_peer.h"
namespace Window { namespace Window {
namespace {
TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller) : TWidget(parent) constexpr auto kThirdSectionInfoTimeoutMs = 1000;
} // namespace
TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller) : RpWidget(parent)
, _controller(controller) , _controller(controller)
, _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton) , _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton)
, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton) , _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)
@ -46,6 +53,7 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
, _mediaType(this, langFactory(lng_media_type), st::topBarButton) , _mediaType(this, langFactory(lng_media_type), st::topBarButton)
, _call(this, st::topBarCall) , _call(this, st::topBarCall)
, _search(this, st::topBarSearch) , _search(this, st::topBarSearch)
, _infoToggle(this, st::topBarInfo)
, _menuToggle(this, st::topBarMenuToggle) { , _menuToggle(this, st::topBarMenuToggle) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); subscribe(Lang::Current().updated(), [this] { refreshLang(); });
@ -58,6 +66,7 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
_call->setClickedCallback([this] { onCall(); }); _call->setClickedCallback([this] { onCall(); });
_search->setClickedCallback([this] { onSearch(); }); _search->setClickedCallback([this] { onSearch(); });
_menuToggle->setClickedCallback([this] { showMenu(); }); _menuToggle->setClickedCallback([this] { showMenu(); });
_infoToggle->setClickedCallback([this] { toggleInfoSection(); });
subscribe(_controller->searchInPeerChanged(), [this](PeerData *peer) { subscribe(_controller->searchInPeerChanged(), [this](PeerData *peer) {
_searchInPeer = peer; _searchInPeer = peer;
@ -85,7 +94,12 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
updateControlsVisibility(); updateControlsVisibility();
} }
})); }));
subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { updateControlsVisibility(); }); subscribe(Global::RefPhoneCallsEnabledChanged(), [this] {
updateControlsVisibility(); });
Auth().data().thirdSectionInfoEnabledValue()
| rpl::on_next([this](bool) { updateInfoToggleActive(); })
| rpl::start(lifetime());
setCursor(style::cur_pointer); setCursor(style::cur_pointer);
updateControlsVisibility(); updateControlsVisibility();
@ -109,7 +123,9 @@ void TopBarWidget::onClearSelection() {
void TopBarWidget::onInfoClicked() { void TopBarWidget::onInfoClicked() {
auto p = App::main() ? App::main()->historyPeer() : nullptr; auto p = App::main() ? App::main()->historyPeer() : nullptr;
if (p) Ui::showPeerProfile(p); if (p) {
_controller->showPeerInfo(p);
}
} }
void TopBarWidget::onSearch() { void TopBarWidget::onSearch() {
@ -163,6 +179,28 @@ void TopBarWidget::showMenu() {
} }
} }
void TopBarWidget::toggleInfoSection() {
if (Adaptive::ThreeColumn()
&& Auth().data().thirdSectionInfoEnabled()) {
_controller->closeThirdSection();
} else if (auto peer = App::main()->historyPeer()) {
if (_controller->canShowThirdSection()) {
Auth().data().setThirdSectionInfoEnabled(true);
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
if (Adaptive::ThreeColumn()) {
_controller->showSection(Info::Memento(peer->id));
} else {
_controller->resizeForThirdSection();
_controller->updateColumnLayout();
}
} else {
_controller->showSection(Info::Memento(peer->id));
}
} else {
updateControlsVisibility();
}
}
bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) { bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
if (obj == _membersShowArea) { if (obj == _membersShowArea) {
switch (e->type()) { switch (e->type()) {
@ -288,10 +326,14 @@ void TopBarWidget::updateControlsGeometry() {
_menuToggle->moveToRight(right, otherButtonsTop); _menuToggle->moveToRight(right, otherButtonsTop);
_mediaType->moveToRight(right, otherButtonsTop); _mediaType->moveToRight(right, otherButtonsTop);
if (_info->isHidden()) { if (_info->isHidden()) {
right += _menuToggle->width(); right += _menuToggle->width() + st::topBarSkip;
} else { } else {
right += _info->width(); right += _info->width();
} }
_infoToggle->moveToRight(right, otherButtonsTop);
if (!_infoToggle->isHidden()) {
right += _infoToggle->width() + st::topBarSkip;
}
_search->moveToRight(right, otherButtonsTop); _search->moveToRight(right, otherButtonsTop);
right += _search->width() + st::topBarCallSkip; right += _search->width() + st::topBarCallSkip;
_call->moveToRight(right, otherButtonsTop); _call->moveToRight(right, otherButtonsTop);
@ -322,6 +364,8 @@ void TopBarWidget::updateControlsVisibility() {
_menuToggle->show(); _menuToggle->show();
} }
_search->show(); _search->show();
_infoToggle->setVisible(!Adaptive::OneColumn()
&& _controller->canShowThirdSection());
auto callsEnabled = false; auto callsEnabled = false;
if (auto user = historyPeer->asUser()) { if (auto user = historyPeer->asUser()) {
callsEnabled = Global::PhoneCallsEnabled() && user->hasCalls(); callsEnabled = Global::PhoneCallsEnabled() && user->hasCalls();
@ -421,6 +465,20 @@ void TopBarWidget::updateAdaptiveLayout() {
rtlupdate(0, 0, st::titleUnreadCounterRight, st::titleUnreadCounterTop); rtlupdate(0, 0, st::titleUnreadCounterRight, st::titleUnreadCounterTop);
}); });
} }
updateInfoToggleActive();
}
void TopBarWidget::updateInfoToggleActive() {
auto infoThirdActive = Adaptive::ThreeColumn()
&& Auth().data().thirdSectionInfoEnabled();
auto iconOverride = infoThirdActive
? &st::topBarInfoActive
: nullptr;
auto ripplOverride = infoThirdActive
? &st::lightButtonBgOver
: nullptr;
_infoToggle->setIconOverride(iconOverride, iconOverride);
_infoToggle->setRippleColorOverride(ripplOverride);
} }
Ui::RoundButton *TopBarWidget::mediaTypeButton() { Ui::RoundButton *TopBarWidget::mediaTypeButton() {

View File

@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include "ui/twidget.h" #include "ui/rp_widget.h"
namespace Ui { namespace Ui {
class PeerAvatarButton; class PeerAvatarButton;
@ -33,7 +33,7 @@ namespace Window {
class Controller; class Controller;
class TopBarWidget : public TWidget, private base::Subscriber { class TopBarWidget : public Ui::RpWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
@ -68,6 +68,7 @@ private:
void refreshLang(); void refreshLang();
void updateControlsGeometry(); void updateControlsGeometry();
void selectedShowCallback(); void selectedShowCallback();
void updateInfoToggleActive();
void onForwardSelection(); void onForwardSelection();
void onDeleteSelection(); void onDeleteSelection();
@ -76,6 +77,7 @@ private:
void onCall(); void onCall();
void onSearch(); void onSearch();
void showMenu(); void showMenu();
void toggleInfoSection();
void updateAdaptiveLayout(); void updateAdaptiveLayout();
int countSelectedButtonsTop(float64 selectedShown); int countSelectedButtonsTop(float64 selectedShown);
@ -97,6 +99,7 @@ private:
object_ptr<Ui::IconButton> _call; object_ptr<Ui::IconButton> _call;
object_ptr<Ui::IconButton> _search; object_ptr<Ui::IconButton> _search;
object_ptr<Ui::IconButton> _infoToggle;
object_ptr<Ui::IconButton> _menuToggle; object_ptr<Ui::IconButton> _menuToggle;
object_ptr<Ui::DropdownMenu> _menu = { nullptr }; object_ptr<Ui::DropdownMenu> _menu = { nullptr };

View File

@ -30,6 +30,10 @@ windowDefaultHeight: 600px;
windowShadow: icon {{ "window_shadow", windowShadowFg }}; windowShadow: icon {{ "window_shadow", windowShadowFg }};
windowShadowShift: 1px; windowShadowShift: 1px;
columnMinimalWidthLeft: 260px;
columnMinimalWidthMain: 380px;
columnMinimalWidthThird: 345px;
adaptiveChatWideWidth: 880px; adaptiveChatWideWidth: 880px;
notifyBorder: windowShadowFgFallback; notifyBorder: windowShadowFgFallback;
@ -257,9 +261,9 @@ topBarSearch: IconButton {
width: 40px; width: 40px;
height: topBarHeight; height: topBarHeight;
icon: icon {{ "title_search-flip_horizontal", menuIconFg }}; icon: icon {{ "top_bar_search", menuIconFg }};
iconOver: icon {{ "title_search-flip_horizontal", menuIconFgOver }}; iconOver: icon {{ "top_bar_search", menuIconFgOver }};
iconPosition: point(11px, 19px); iconPosition: point(4px, 11px);
rippleAreaPosition: point(0px, 7px); rippleAreaPosition: point(0px, 7px);
rippleAreaSize: 40px; rippleAreaSize: 40px;
@ -268,10 +272,16 @@ topBarSearch: IconButton {
} }
} }
topBarCall: IconButton(topBarSearch) { topBarCall: IconButton(topBarSearch) {
icon: icon {{ "add_contact_phone", menuIconFg }}; icon: icon {{ "top_bar_call", menuIconFg }};
iconOver: icon {{ "add_contact_phone", menuIconFgOver }}; iconOver: icon {{ "top_bar_call", menuIconFgOver }};
} }
topBarCallSkip: 4px; topBarInfo: IconButton(topBarSearch) {
icon: icon {{ "top_bar_profile", menuIconFg }};
iconOver: icon {{ "top_bar_profile", menuIconFgOver }};
}
topBarInfoActive: icon {{ "top_bar_profile", windowBgActive }};
topBarSkip: -2px;
topBarCallSkip: -1px;
topBarMenuToggle: IconButton(topBarSearch) { topBarMenuToggle: IconButton(topBarSearch) {
width: 44px; width: 44px;

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/main_window.h" #include "window/main_window.h"
#include "info/info_memento.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "styles/style_window.h" #include "styles/style_window.h"
@ -30,6 +31,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "apiwrap.h" #include "apiwrap.h"
namespace Window { namespace Window {
namespace {
constexpr auto kThirdSectionInfoTimeoutMs = 1000;
} // namespace
void Controller::enableGifPauseReason(GifPauseReason reason) { void Controller::enableGifPauseReason(GifPauseReason reason) {
if (!(_gifPauseReasons & reason)) { if (!(_gifPauseReasons & reason)) {
@ -61,21 +67,29 @@ int Controller::dialogsSmallColumnWidth() const {
return st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x(); return st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x();
} }
int Controller::minimalThreeColumnWidth() const {
return st::columnMinimalWidthLeft
+ st::columnMinimalWidthMain
+ st::columnMinimalWidthThird;
}
Controller::ColumnLayout Controller::computeColumnLayout() const { Controller::ColumnLayout Controller::computeColumnLayout() const {
auto layout = Adaptive::WindowLayout::OneColumn; auto layout = Adaptive::WindowLayout::OneColumn;
auto bodyWidth = window()->bodyWidget()->width(); auto bodyWidth = window()->bodyWidget()->width();
auto dialogsWidth = qRound(bodyWidth * dialogsWidthRatio().value()); auto dialogsWidth = qRound(bodyWidth * dialogsWidthRatio().value());
auto chatWidth = bodyWidth - dialogsWidth; auto chatWidth = bodyWidth - dialogsWidth;
accumulate_max(chatWidth, st::windowMinWidth); auto thirdWidth = 0;
accumulate_max(chatWidth, st::columnMinimalWidthMain);
dialogsWidth = bodyWidth - chatWidth; dialogsWidth = bodyWidth - chatWidth;
auto useOneColumnLayout = [this, bodyWidth, dialogsWidth] { auto useOneColumnLayout = [this, bodyWidth, dialogsWidth] {
auto someSectionShown = !App::main()->selectingPeer() && App::main()->isSectionShown(); if (dialogsWidth < st::dialogsPadding.x() && Adaptive::OneColumn()) {
if (dialogsWidth < st::dialogsPadding.x() && (Adaptive::OneColumn() || someSectionShown)) {
return true; return true;
} }
if (bodyWidth < st::windowMinWidth + st::dialogsWidthMin) { auto minimalNormal = st::columnMinimalWidthLeft
+ st::columnMinimalWidthMain;
if (bodyWidth < minimalNormal) {
return true; return true;
} }
return false; return false;
@ -89,6 +103,18 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
return false; return false;
}; };
auto useNormalLayout = [this, bodyWidth] {
// Used if useSmallColumnLayout() == false.
if (bodyWidth < minimalThreeColumnWidth()) {
return true;
}
if (!Auth().data().tabbedSelectorSectionEnabled()
&& !Auth().data().thirdSectionInfoEnabled()) {
return true;
}
return false;
};
if (useOneColumnLayout()) { if (useOneColumnLayout()) {
dialogsWidth = chatWidth = bodyWidth; dialogsWidth = chatWidth = bodyWidth;
} else if (useSmallColumnLayout()) { } else if (useSmallColumnLayout()) {
@ -99,7 +125,7 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
} else if (dialogsListFocused().value()) { } else if (dialogsListFocused().value()) {
return true; return true;
} }
return !App::main()->isSectionShown(); return !App::main()->isMainSectionShown();
}; };
if (forceWideDialogs()) { if (forceWideDialogs()) {
dialogsWidth = st::dialogsWidthMin; dialogsWidth = st::dialogsWidthMin;
@ -107,33 +133,81 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
dialogsWidth = dialogsSmallColumnWidth(); dialogsWidth = dialogsSmallColumnWidth();
} }
chatWidth = bodyWidth - dialogsWidth; chatWidth = bodyWidth - dialogsWidth;
} else { } else if (useNormalLayout()) {
layout = Adaptive::WindowLayout::Normal; layout = Adaptive::WindowLayout::Normal;
accumulate_max(dialogsWidth, st::dialogsWidthMin); accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
chatWidth = bodyWidth - dialogsWidth; chatWidth = bodyWidth - dialogsWidth;
} else {
layout = Adaptive::WindowLayout::ThreeColumn;
accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
thirdWidth = st::columnMinimalWidthThird;
accumulate_min(
dialogsWidth,
bodyWidth - thirdWidth - st::columnMinimalWidthMain);
chatWidth = bodyWidth - dialogsWidth - thirdWidth;
} }
return { bodyWidth, dialogsWidth, chatWidth, layout }; return { bodyWidth, dialogsWidth, chatWidth, thirdWidth, layout };
} }
bool Controller::canProvideChatWidth(int requestedWidth) const { bool Controller::canShowThirdSection() const {
auto currentLayout = computeColumnLayout(); auto currentLayout = computeColumnLayout();
auto extendBy = requestedWidth - currentLayout.chatWidth; auto extendBy = minimalThreeColumnWidth()
- currentLayout.bodyWidth;
if (extendBy <= 0) { if (extendBy <= 0) {
return true; return true;
} }
return window()->canExtendWidthBy(extendBy); return window()->canExtendWidthBy(extendBy);
} }
void Controller::provideChatWidth(int requestedWidth) { void Controller::resizeForThirdSection() {
auto currentLayout = computeColumnLayout(); auto layout = computeColumnLayout();
auto extendBy = requestedWidth - currentLayout.chatWidth; if (layout.windowLayout == Adaptive::WindowLayout::ThreeColumn) {
if (extendBy <= 0) {
return; return;
} }
auto tabbedSelectorSectionEnabled =
Auth().data().tabbedSelectorSectionEnabled();
auto thirdSectionInfoEnabled =
Auth().data().thirdSectionInfoEnabled();
Auth().data().setTabbedSelectorSectionEnabled(false);
Auth().data().setThirdSectionInfoEnabled(false);
auto extendBy = st::columnMinimalWidthThird;
auto newBodyWidth = layout.bodyWidth + extendBy;
dialogsWidthRatio().set(
float64(layout.dialogsWidth) / newBodyWidth,
true);
window()->tryToExtendWidthBy(extendBy); window()->tryToExtendWidthBy(extendBy);
auto newLayout = computeColumnLayout();
if (newLayout.windowLayout != Adaptive::WindowLayout::OneColumn) { Auth().data().setTabbedSelectorSectionEnabled(
dialogsWidthRatio().set(float64(newLayout.bodyWidth - requestedWidth) / newLayout.bodyWidth, true); tabbedSelectorSectionEnabled);
Auth().data().setThirdSectionInfoEnabled(
thirdSectionInfoEnabled);
}
void Controller::closeThirdSection() {
auto newWindowSize = window()->size();
auto layout = computeColumnLayout();
if (layout.windowLayout == Adaptive::WindowLayout::ThreeColumn) {
auto noResize = window()->isFullScreen()
|| window()->isMaximized();
auto newBodyWidth = noResize
? layout.bodyWidth
: (layout.bodyWidth - layout.thirdWidth);
dialogsWidthRatio().set(
float64(layout.dialogsWidth) / newBodyWidth,
true);
newWindowSize = QSize(
window()->width() + (newBodyWidth - layout.bodyWidth),
window()->height());
}
Auth().data().setTabbedSelectorSectionEnabled(false);
Auth().data().setThirdSectionInfoEnabled(false);
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
if (window()->size() != newWindowSize) {
window()->resize(newWindowSize);
} else {
updateColumnLayout();
} }
} }
@ -184,15 +258,57 @@ void Controller::showJumpToDate(not_null<PeerData*> peer, QDate requestedDate) {
Ui::show(std::move(box)); Ui::show(std::move(box));
} }
void Controller::updateColumnLayout() {
App::main()->updateColumnLayout();
}
void Controller::showPeerHistory(
PeerId peerId,
Ui::ShowWay way,
MsgId msgId) {
Ui::showPeerHistory(peerId, msgId, way);
}
void Controller::showPeerHistory( void Controller::showPeerHistory(
not_null<PeerData*> peer, not_null<PeerData*> peer,
Ui::ShowWay way, Ui::ShowWay way,
MsgId msgId) { MsgId msgId) {
Ui::showPeerHistory(peer, msgId, way); showPeerHistory(peer->id, way, msgId);
} }
void Controller::showWideSection(SectionMemento &&memento) { void Controller::showPeerHistory(
App::main()->showWideSection(std::move(memento)); not_null<History*> history,
Ui::ShowWay way,
MsgId msgId) {
showPeerHistory(history->peer->id, way, msgId);
}
void Controller::showPeerInfo(
PeerId peerId,
anim::type animated) {
if (Adaptive::ThreeColumn()) {
Auth().data().setThirdSectionInfoEnabled(true);
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
}
showSection(Info::Memento(peerId), animated);
}
void Controller::showPeerInfo(
not_null<PeerData*> peer,
anim::type animated) {
showPeerInfo(peer->id, animated);
}
void Controller::showPeerInfo(
not_null<History*> history,
anim::type animated) {
showPeerInfo(history->peer->id, animated);
}
void Controller::showSection(
SectionMemento &&memento,
anim::type animated) {
App::main()->showSection(std::move(memento), animated);
} }
void Controller::showBackFromStack() { void Controller::showBackFromStack() {

View File

@ -78,12 +78,47 @@ public:
int bodyWidth; int bodyWidth;
int dialogsWidth; int dialogsWidth;
int chatWidth; int chatWidth;
int thirdWidth;
Adaptive::WindowLayout windowLayout; Adaptive::WindowLayout windowLayout;
}; };
ColumnLayout computeColumnLayout() const; ColumnLayout computeColumnLayout() const;
int dialogsSmallColumnWidth() const; int dialogsSmallColumnWidth() const;
bool canProvideChatWidth(int requestedWidth) const; void updateColumnLayout();
void provideChatWidth(int requestedWidth); bool canShowThirdSection() const;
void resizeForThirdSection();
void closeThirdSection();
void showSection(
SectionMemento &&memento,
anim::type animated = anim::type::normal);
void showBackFromStack();
void showSpecialLayer(
object_ptr<LayerWidget> &&layer,
LayerOptions options = LayerOption::Animated);
void hideSpecialLayer(
LayerOptions options = LayerOption::Animated);
void showPeerHistory(
PeerId peerId,
Ui::ShowWay way = Ui::ShowWay::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void showPeerHistory(
not_null<PeerData*> peer,
Ui::ShowWay way = Ui::ShowWay::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void showPeerHistory(
not_null<History*> history,
Ui::ShowWay way = Ui::ShowWay::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void showPeerInfo(
PeerId peerId,
anim::type animated = anim::type::normal);
void showPeerInfo(
not_null<PeerData*> peer,
anim::type animated = anim::type::normal);
void showPeerInfo(
not_null<History*> history,
anim::type animated = anim::type::normal);
void showJumpToDate(not_null<PeerData*> peer, QDate requestedDate); void showJumpToDate(not_null<PeerData*> peer, QDate requestedDate);
@ -106,19 +141,8 @@ public:
return _dialogsListDisplayForced; return _dialogsListDisplayForced;
} }
void showPeerHistory(
not_null<PeerData*> peer,
Ui::ShowWay way = Ui::ShowWay::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void showWideSection(SectionMemento &&memento);
void showBackFromStack();
void showSpecialLayer(
object_ptr<LayerWidget> &&layer,
LayerOptions options = LayerOption::Animated);
void hideSpecialLayer(
LayerOptions options = LayerOption::Animated);
private: private:
int minimalThreeColumnWidth() const;
not_null<MainWidget*> chats() const; not_null<MainWidget*> chats() const;
not_null<MainWindow*> _window; not_null<MainWindow*> _window;