mirror of https://github.com/procxx/kepka.git
Add TabbedSection which uses the TabbedSelector.
This commit is contained in:
parent
647ea44881
commit
891d200e2d
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
|
#include "storage/localstorage.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
|
||||||
QByteArray AuthSessionData::serialize() const {
|
QByteArray AuthSessionData::serialize() const {
|
||||||
|
@ -40,6 +41,7 @@ QByteArray AuthSessionData::serialize() const {
|
||||||
stream.setVersion(QDataStream::Qt_5_1);
|
stream.setVersion(QDataStream::Qt_5_1);
|
||||||
stream << static_cast<qint32>(_variables.emojiPanelTab);
|
stream << static_cast<qint32>(_variables.emojiPanelTab);
|
||||||
stream << qint32(_variables.lastSeenWarningSeen ? 1 : 0);
|
stream << qint32(_variables.lastSeenWarningSeen ? 1 : 0);
|
||||||
|
stream << qint32(_variables.tabbedSelectorSectionEnabled ? 1 : 0);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +60,12 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||||
stream.setVersion(QDataStream::Qt_5_1);
|
stream.setVersion(QDataStream::Qt_5_1);
|
||||||
qint32 emojiPanTab = static_cast<qint32>(EmojiPanelTab::Emoji);
|
qint32 emojiPanTab = static_cast<qint32>(EmojiPanelTab::Emoji);
|
||||||
qint32 lastSeenWarningSeen = 0;
|
qint32 lastSeenWarningSeen = 0;
|
||||||
|
qint32 tabbedSelectorSectionEnabled = 1;
|
||||||
stream >> emojiPanTab;
|
stream >> emojiPanTab;
|
||||||
stream >> lastSeenWarningSeen;
|
stream >> lastSeenWarningSeen;
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
stream >> tabbedSelectorSectionEnabled;
|
||||||
|
}
|
||||||
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;
|
||||||
|
@ -72,6 +78,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||||
case EmojiPanelTab::Gifs: _variables.emojiPanelTab = uncheckedTab; break;
|
case EmojiPanelTab::Gifs: _variables.emojiPanelTab = uncheckedTab; break;
|
||||||
}
|
}
|
||||||
_variables.lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
_variables.lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
||||||
|
_variables.tabbedSelectorSectionEnabled = (tabbedSelectorSectionEnabled == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthSession::AuthSession(UserId userId)
|
AuthSession::AuthSession(UserId userId)
|
||||||
|
@ -80,6 +87,9 @@ AuthSession::AuthSession(UserId userId)
|
||||||
, _downloader(std::make_unique<Storage::Downloader>())
|
, _downloader(std::make_unique<Storage::Downloader>())
|
||||||
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
|
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
|
||||||
Expects(_userId != 0);
|
Expects(_userId != 0);
|
||||||
|
_saveDataTimer.setCallback([this] {
|
||||||
|
Local::writeUserSettings();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthSession::Exists() {
|
bool AuthSession::Exists() {
|
||||||
|
@ -109,4 +119,9 @@ bool AuthSession::validateSelf(const MTPUser &user) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthSession::saveDataDelayed(TimeMs delay) {
|
||||||
|
Expects(this == &AuthSession::Current());
|
||||||
|
_saveDataTimer.callOnce(delay);
|
||||||
|
}
|
||||||
|
|
||||||
AuthSession::~AuthSession() = default;
|
AuthSession::~AuthSession() = default;
|
||||||
|
|
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
class Downloader;
|
class Downloader;
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
@ -71,11 +73,18 @@ public:
|
||||||
void setEmojiPanelTab(EmojiPanelTab tab) {
|
void setEmojiPanelTab(EmojiPanelTab tab) {
|
||||||
_variables.emojiPanelTab = tab;
|
_variables.emojiPanelTab = tab;
|
||||||
}
|
}
|
||||||
|
bool tabbedSelectorSectionEnabled() const {
|
||||||
|
return _variables.tabbedSelectorSectionEnabled;
|
||||||
|
}
|
||||||
|
void setTabbedSelectorSectionEnabled(bool enabled) {
|
||||||
|
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Variables {
|
struct Variables {
|
||||||
bool lastSeenWarningSeen = false;
|
bool lastSeenWarningSeen = false;
|
||||||
EmojiPanelTab emojiPanelTab = EmojiPanelTab::Emoji;
|
EmojiPanelTab emojiPanelTab = EmojiPanelTab::Emoji;
|
||||||
|
bool tabbedSelectorSectionEnabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
base::Variable<bool> _contactsLoaded = { false };
|
base::Variable<bool> _contactsLoaded = { false };
|
||||||
|
@ -122,6 +131,7 @@ public:
|
||||||
AuthSessionData &data() {
|
AuthSessionData &data() {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
void saveDataDelayed(TimeMs delay);
|
||||||
|
|
||||||
ApiWrap &api() {
|
ApiWrap &api() {
|
||||||
return *_api;
|
return *_api;
|
||||||
|
@ -132,6 +142,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const UserId _userId = 0;
|
const UserId _userId = 0;
|
||||||
AuthSessionData _data;
|
AuthSessionData _data;
|
||||||
|
base::Timer _saveDataTimer;
|
||||||
|
|
||||||
const std::unique_ptr<ApiWrap> _api;
|
const std::unique_ptr<ApiWrap> _api;
|
||||||
const std::unique_ptr<Storage::Downloader> _downloader;
|
const std::unique_ptr<Storage::Downloader> _downloader;
|
||||||
|
|
|
@ -107,7 +107,11 @@ stickersSettingsUnreadPosition: point(4px, 5px);
|
||||||
|
|
||||||
emojiPanMargins: margins(10px, 10px, 10px, 10px);
|
emojiPanMargins: margins(10px, 10px, 10px, 10px);
|
||||||
|
|
||||||
emojiTabs: defaultTabsSlider;
|
emojiTabs: SettingsSlider(defaultTabsSlider) {
|
||||||
|
height: 55px;
|
||||||
|
barTop: 52px;
|
||||||
|
labelTop: 19px;
|
||||||
|
}
|
||||||
emojiScroll: defaultSolidScroll;
|
emojiScroll: defaultSolidScroll;
|
||||||
emojiRecent: icon {{ "emoji_recent", emojiIconFg }};
|
emojiRecent: icon {{ "emoji_recent", emojiIconFg }};
|
||||||
emojiRecentActive: icon {{ "emoji_recent", emojiIconFgActive }};
|
emojiRecentActive: icon {{ "emoji_recent", emojiIconFgActive }};
|
||||||
|
|
|
@ -103,7 +103,10 @@ void GifsListWidget::Footer::stealFocus() {
|
||||||
|
|
||||||
void GifsListWidget::Footer::returnFocus() {
|
void GifsListWidget::Footer::returnFocus() {
|
||||||
if (_focusTakenFrom) {
|
if (_focusTakenFrom) {
|
||||||
_focusTakenFrom->setFocus();
|
if (_field->hasFocus()) {
|
||||||
|
_focusTakenFrom->setFocus();
|
||||||
|
}
|
||||||
|
_focusTakenFrom = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct StickerIcon {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StickersListWidget::Footer : public TabbedSelector::InnerFooter {
|
class StickersListWidget::Footer : public TabbedSelector::InnerFooter, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
Footer(gsl::not_null<StickersListWidget*> parent);
|
Footer(gsl::not_null<StickersListWidget*> parent);
|
||||||
|
|
||||||
|
@ -112,6 +112,10 @@ StickersListWidget::Footer::Footer(gsl::not_null<StickersListWidget*> parent) :
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
_iconsLeft = (st::emojiPanWidth - kVisibleIconsCount * st::emojiCategory.width) / 2;
|
_iconsLeft = (st::emojiPanWidth - kVisibleIconsCount * st::emojiCategory.width) / 2;
|
||||||
|
|
||||||
|
subscribe(AuthSession::CurrentDownloaderTaskFinished(), [this] {
|
||||||
|
update();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
|
@ -905,13 +909,13 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
emit selected(set.pack[sticker->index]);
|
emit selected(set.pack[sticker->index]);
|
||||||
} else if (auto set = base::get_if<OverSet>(&pressed)) {
|
} else if (auto set = base::get_if<OverSet>(&pressed)) {
|
||||||
t_assert(set->section >= 0 && set->section < sets.size());
|
t_assert(set->section >= 0 && set->section < sets.size());
|
||||||
emit displaySet(sets[set->section].id);
|
displaySet(sets[set->section].id);
|
||||||
} else if (auto button = base::get_if<OverButton>(&pressed)) {
|
} else if (auto button = base::get_if<OverButton>(&pressed)) {
|
||||||
t_assert(button->section >= 0 && button->section < sets.size());
|
t_assert(button->section >= 0 && button->section < sets.size());
|
||||||
if (_section == Section::Featured) {
|
if (_section == Section::Featured) {
|
||||||
emit installSet(sets[button->section].id);
|
installSet(sets[button->section].id);
|
||||||
} else {
|
} else {
|
||||||
emit removeSet(sets[button->section].id);
|
removeSet(sets[button->section].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1385,22 +1389,22 @@ void StickersListWidget::installSet(quint64 setId) {
|
||||||
void StickersListWidget::removeSet(quint64 setId) {
|
void StickersListWidget::removeSet(quint64 setId) {
|
||||||
auto &sets = Global::StickerSets();
|
auto &sets = Global::StickerSets();
|
||||||
auto it = sets.constFind(setId);
|
auto it = sets.constFind(setId);
|
||||||
if (it != sets.cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
|
if (it != sets.cend()) {
|
||||||
_removingSetId = it->id;
|
_removingSetId = it->id;
|
||||||
auto text = lng_stickers_remove_pack(lt_sticker_pack, it->title);
|
auto text = lng_stickers_remove_pack(lt_sticker_pack, it->title);
|
||||||
Ui::show(Box<ConfirmBox>(text, lang(lng_box_remove), base::lambda_guarded(this, [this] {
|
Ui::show(Box<ConfirmBox>(text, lang(lng_box_remove), base::lambda_guarded(this, [this] {
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
auto &sets = Global::RefStickerSets();
|
auto &sets = Global::RefStickerSets();
|
||||||
auto it = sets.find(_removingSetId);
|
auto it = sets.find(_removingSetId);
|
||||||
if (it != sets.cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
|
if (it != sets.cend()) {
|
||||||
if (it->id && it->access) {
|
if (it->id && it->access) {
|
||||||
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)))).send();
|
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)))).send();
|
||||||
} else if (!it->shortName.isEmpty()) {
|
} else if (!it->shortName.isEmpty()) {
|
||||||
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetShortName(MTP_string(it->shortName)))).send();
|
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetShortName(MTP_string(it->shortName)))).send();
|
||||||
}
|
}
|
||||||
bool writeRecent = false;
|
auto writeRecent = false;
|
||||||
RecentStickerPack &recent(cGetRecentStickers());
|
auto &recent = cGetRecentStickers();
|
||||||
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
for (auto i = recent.begin(); i != recent.cend();) {
|
||||||
if (it->stickers.indexOf(i->first) >= 0) {
|
if (it->stickers.indexOf(i->first) >= 0) {
|
||||||
i = recent.erase(i);
|
i = recent.erase(i);
|
||||||
writeRecent = true;
|
writeRecent = true;
|
||||||
|
|
|
@ -33,8 +33,12 @@ constexpr auto kDelayedHideTimeoutMs = 3000;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TabbedPanel::TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TWidget(parent)
|
TabbedPanel::TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TabbedPanel(parent, controller, object_ptr<TabbedSelector>(nullptr, controller)) {
|
||||||
, _selector(this, controller) {
|
}
|
||||||
|
|
||||||
|
TabbedPanel::TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : TWidget(parent)
|
||||||
|
, _selector(std::move(selector)) {
|
||||||
|
_selector->setParent(this);
|
||||||
_selector->setRoundRadius(st::buttonRadius);
|
_selector->setRoundRadius(st::buttonRadius);
|
||||||
|
|
||||||
resize(QRect(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight).marginsAdded(innerPadding()).size());
|
resize(QRect(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight).marginsAdded(innerPadding()).size());
|
||||||
|
@ -47,11 +51,11 @@ TabbedPanel::TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> con
|
||||||
|
|
||||||
_hideTimer.setCallback([this] { hideByTimerOrLeave(); });
|
_hideTimer.setCallback([this] { hideByTimerOrLeave(); });
|
||||||
|
|
||||||
connect(_selector, SIGNAL(checkForHide()), this, SLOT(onCheckForHide()));
|
connect(_selector, &TabbedSelector::checkForHide, this, [this] {
|
||||||
connect(_selector, SIGNAL(emojiSelected(EmojiPtr)), this, SIGNAL(emojiSelected(EmojiPtr)));
|
if (!rect().contains(mapFromGlobal(QCursor::pos()))) {
|
||||||
connect(_selector, SIGNAL(stickerSelected(DocumentData*)), this, SIGNAL(stickerSelected(DocumentData*)));
|
_hideTimer.callOnce(kDelayedHideTimeoutMs);
|
||||||
connect(_selector, SIGNAL(photoSelected(PhotoData*)), this, SIGNAL(photoSelected(PhotoData*)));
|
}
|
||||||
connect(_selector, SIGNAL(inlineResultSelected(InlineBots::Result*,UserData*)), this, SIGNAL(inlineResultSelected(InlineBots::Result*,UserData*)));
|
});
|
||||||
connect(_selector, &TabbedSelector::cancelled, this, [this] {
|
connect(_selector, &TabbedSelector::cancelled, this, [this] {
|
||||||
hideAnimated();
|
hideAnimated();
|
||||||
});
|
});
|
||||||
|
@ -77,6 +81,10 @@ void TabbedPanel::moveBottom(int bottom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::updateContentHeight() {
|
void TabbedPanel::updateContentHeight() {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto addedHeight = innerPadding().top() + innerPadding().bottom();
|
auto addedHeight = innerPadding().top() + innerPadding().bottom();
|
||||||
auto wantedContentHeight = qRound(st::emojiPanHeightRatio * _bottom) - addedHeight;
|
auto wantedContentHeight = qRound(st::emojiPanHeightRatio * _bottom) - addedHeight;
|
||||||
auto contentHeight = snap(wantedContentHeight, st::emojiPanMinHeight, st::emojiPanMaxHeight);
|
auto contentHeight = snap(wantedContentHeight, st::emojiPanMinHeight, st::emojiPanMaxHeight);
|
||||||
|
@ -98,8 +106,8 @@ void TabbedPanel::updateContentHeight() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::onWndActiveChanged() {
|
void TabbedPanel::onWndActiveChanged() {
|
||||||
if (!App::wnd()->windowHandle()->isActive() && !isHidden()) {
|
if (!App::wnd()->windowHandle()->isActive() && !isHidden() && !preventAutoHide()) {
|
||||||
leaveEvent(0);
|
hideAnimated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +122,7 @@ void TabbedPanel::paintEvent(QPaintEvent *e) {
|
||||||
auto showAnimating = _a_show.animating(ms);
|
auto showAnimating = _a_show.animating(ms);
|
||||||
if (_showAnimation && !showAnimating) {
|
if (_showAnimation && !showAnimating) {
|
||||||
_showAnimation.reset();
|
_showAnimation.reset();
|
||||||
if (!opacityAnimating) {
|
if (!opacityAnimating && !isDestroying()) {
|
||||||
showChildren();
|
showChildren();
|
||||||
_selector->afterShown();
|
_selector->afterShown();
|
||||||
}
|
}
|
||||||
|
@ -146,6 +154,9 @@ void TabbedPanel::enterEventHook(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabbedPanel::preventAutoHide() const {
|
bool TabbedPanel::preventAutoHide() const {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return _selector->preventAutoHide();
|
return _selector->preventAutoHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,14 +199,10 @@ void TabbedPanel::hideFast() {
|
||||||
hideFinished();
|
hideFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::refreshStickers() {
|
|
||||||
_selector->refreshStickers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TabbedPanel::opacityAnimationCallback() {
|
void TabbedPanel::opacityAnimationCallback() {
|
||||||
update();
|
update();
|
||||||
if (!_a_opacity.animating()) {
|
if (!_a_opacity.animating()) {
|
||||||
if (_hiding) {
|
if (_hiding || isDestroying()) {
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
hideFinished();
|
hideFinished();
|
||||||
} else if (!_a_show.animating()) {
|
} else if (!_a_show.animating()) {
|
||||||
|
@ -226,7 +233,7 @@ void TabbedPanel::prepareCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::startOpacityAnimation(bool hiding) {
|
void TabbedPanel::startOpacityAnimation(bool hiding) {
|
||||||
if (!_selector->isHidden()) {
|
if (_selector && !_selector->isHidden()) {
|
||||||
_selector->beforeHiding();
|
_selector->beforeHiding();
|
||||||
}
|
}
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
|
@ -259,12 +266,13 @@ QImage TabbedPanel::grabForAnimation() {
|
||||||
|
|
||||||
showChildren();
|
showChildren();
|
||||||
myEnsureResized(this);
|
myEnsureResized(this);
|
||||||
myEnsureResized(_selector);
|
|
||||||
|
|
||||||
auto result = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
auto result = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
result.setDevicePixelRatio(cRetinaFactor());
|
result.setDevicePixelRatio(cRetinaFactor());
|
||||||
result.fill(Qt::transparent);
|
result.fill(Qt::transparent);
|
||||||
_selector->render(&result, _selector->geometry().topLeft());
|
if (_selector) {
|
||||||
|
_selector->render(&result, _selector->geometry().topLeft());
|
||||||
|
}
|
||||||
|
|
||||||
_a_show = base::take(showAnimation);
|
_a_show = base::take(showAnimation);
|
||||||
_showAnimation = base::take(showAnimationData);
|
_showAnimation = base::take(showAnimationData);
|
||||||
|
@ -275,26 +283,50 @@ QImage TabbedPanel::grabForAnimation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::hideAnimated() {
|
void TabbedPanel::hideAnimated() {
|
||||||
if (isHidden()) return;
|
if (isHidden() || _hiding) {
|
||||||
if (_hiding) return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_hideTimer.cancel();
|
_hideTimer.cancel();
|
||||||
if (_selector->isSliding()) {
|
if (!isDestroying() && _selector->isSliding()) {
|
||||||
_hideAfterSlide = true;
|
_hideAfterSlide = true;
|
||||||
} else {
|
} else {
|
||||||
startOpacityAnimation(true);
|
startOpacityAnimation(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabbedPanel::~TabbedPanel() = default;
|
void TabbedPanel::toggleAnimated() {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isHidden() || _hiding || _hideAfterSlide) {
|
||||||
|
showAnimated();
|
||||||
|
} else {
|
||||||
|
hideAnimated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<TabbedSelector> TabbedPanel::takeSelector() {
|
||||||
|
auto result = std::move(_selector);
|
||||||
|
hideAnimated();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointer<TabbedSelector> TabbedPanel::getSelector() const {
|
||||||
|
return _selector.data();
|
||||||
|
}
|
||||||
|
|
||||||
void TabbedPanel::hideFinished() {
|
void TabbedPanel::hideFinished() {
|
||||||
hide();
|
hide();
|
||||||
_selector->hideFinished();
|
|
||||||
_a_show.finish();
|
_a_show.finish();
|
||||||
_showAnimation.reset();
|
_showAnimation.reset();
|
||||||
_cache = QPixmap();
|
_cache = QPixmap();
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
|
if (isDestroying()) {
|
||||||
|
deleteLater();
|
||||||
|
} else {
|
||||||
|
_selector->hideFinished();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::showAnimated() {
|
void TabbedPanel::showAnimated() {
|
||||||
|
@ -304,6 +336,9 @@ void TabbedPanel::showAnimated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::showStarted() {
|
void TabbedPanel::showStarted() {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
_selector->showStarted();
|
_selector->showStarted();
|
||||||
moveByBottom();
|
moveByBottom();
|
||||||
|
@ -315,21 +350,21 @@ void TabbedPanel::showStarted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
|
bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (e->type() == QEvent::Enter) {
|
if (e->type() == QEvent::Enter) {
|
||||||
otherEnter();
|
otherEnter();
|
||||||
} else if (e->type() == QEvent::Leave) {
|
} else if (e->type() == QEvent::Leave) {
|
||||||
otherLeave();
|
otherLeave();
|
||||||
} else if (e->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(e)->button() == Qt::LeftButton/* && !dynamic_cast<StickerPan*>(obj)*/) {
|
|
||||||
if (isHidden() || _hiding || _hideAfterSlide) {
|
|
||||||
showAnimated();
|
|
||||||
} else {
|
|
||||||
hideAnimated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::stickersInstalled(uint64 setId) {
|
void TabbedPanel::stickersInstalled(uint64 setId) {
|
||||||
|
if (isDestroying()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_selector->stickersInstalled(setId);
|
_selector->stickersInstalled(setId);
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
moveByBottom();
|
moveByBottom();
|
||||||
|
@ -340,10 +375,6 @@ void TabbedPanel::stickersInstalled(uint64 setId) {
|
||||||
showAnimated();
|
showAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::setInlineQueryPeer(PeerData *peer) {
|
|
||||||
_selector->setInlineQueryPeer(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
style::margins TabbedPanel::innerPadding() const {
|
style::margins TabbedPanel::innerPadding() const {
|
||||||
return st::emojiPanMargins;
|
return st::emojiPanMargins;
|
||||||
}
|
}
|
||||||
|
@ -360,12 +391,6 @@ QRect TabbedPanel::verticalRect() const {
|
||||||
return innerRect().marginsRemoved(style::margins(st::buttonRadius, 0, st::buttonRadius, 0));
|
return innerRect().marginsRemoved(style::margins(st::buttonRadius, 0, st::buttonRadius, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::onCheckForHide() {
|
|
||||||
if (!rect().contains(mapFromGlobal(QCursor::pos()))) {
|
|
||||||
_hideTimer.callOnce(kDelayedHideTimeoutMs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TabbedPanel::overlaps(const QRect &globalRect) const {
|
bool TabbedPanel::overlaps(const QRect &globalRect) const {
|
||||||
if (isHidden() || !_cache.isNull()) return false;
|
if (isHidden() || !_cache.isNull()) return false;
|
||||||
|
|
||||||
|
@ -375,4 +400,6 @@ bool TabbedPanel::overlaps(const QRect &globalRect) const {
|
||||||
|| inner.marginsRemoved(QMargins(0, st::buttonRadius, 0, st::buttonRadius)).contains(testRect);
|
|| inner.marginsRemoved(QMargins(0, st::buttonRadius, 0, st::buttonRadius)).contains(testRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TabbedPanel::~TabbedPanel() = default;
|
||||||
|
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -21,19 +21,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/twidget.h"
|
#include "ui/twidget.h"
|
||||||
#include "ui/effects/panel_animation.h"
|
|
||||||
#include "mtproto/sender.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
|
||||||
namespace InlineBots {
|
|
||||||
class Result;
|
|
||||||
} // namespace InlineBots
|
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class Controller;
|
class Controller;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PanelAnimation;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
|
|
||||||
class TabbedSelector;
|
class TabbedSelector;
|
||||||
|
@ -43,7 +40,10 @@ class TabbedPanel : public TWidget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller);
|
TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller);
|
||||||
|
TabbedPanel(QWidget *parent, gsl::not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector);
|
||||||
|
|
||||||
|
object_ptr<TabbedSelector> takeSelector();
|
||||||
|
QPointer<TabbedSelector> getSelector() const;
|
||||||
void moveBottom(int bottom);
|
void moveBottom(int bottom);
|
||||||
|
|
||||||
void hideFast();
|
void hideFast();
|
||||||
|
@ -54,12 +54,10 @@ public:
|
||||||
void stickersInstalled(uint64 setId);
|
void stickersInstalled(uint64 setId);
|
||||||
|
|
||||||
bool overlaps(const QRect &globalRect) const;
|
bool overlaps(const QRect &globalRect) const;
|
||||||
void setInlineQueryPeer(PeerData *peer);
|
|
||||||
|
|
||||||
void showAnimated();
|
void showAnimated();
|
||||||
void hideAnimated();
|
void hideAnimated();
|
||||||
|
void toggleAnimated();
|
||||||
void refreshStickers();
|
|
||||||
|
|
||||||
~TabbedPanel();
|
~TabbedPanel();
|
||||||
|
|
||||||
|
@ -74,19 +72,13 @@ protected:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onWndActiveChanged();
|
void onWndActiveChanged();
|
||||||
void onCheckForHide();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void emojiSelected(EmojiPtr emoji);
|
|
||||||
void stickerSelected(DocumentData *sticker);
|
|
||||||
void photoSelected(PhotoData *photo);
|
|
||||||
void inlineResultSelected(InlineBots::Result *result, UserData *bot);
|
|
||||||
|
|
||||||
void updateStickers();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void hideByTimerOrLeave();
|
void hideByTimerOrLeave();
|
||||||
void moveByBottom();
|
void moveByBottom();
|
||||||
|
bool isDestroying() const {
|
||||||
|
return !_selector;
|
||||||
|
}
|
||||||
|
|
||||||
style::margins innerPadding() const;
|
style::margins innerPadding() const;
|
||||||
|
|
||||||
|
|
|
@ -20,3 +20,54 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "chat_helpers/tabbed_section.h"
|
#include "chat_helpers/tabbed_section.h"
|
||||||
|
|
||||||
|
#include "styles/style_chat_helpers.h"
|
||||||
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
|
|
||||||
|
namespace ChatHelpers {
|
||||||
|
|
||||||
|
TabbedSection::TabbedSection(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TabbedSection(parent, controller, object_ptr<TabbedSelector>(this, controller)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TabbedSection::TabbedSection(QWidget *parent, gsl::not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : TWidget(parent)
|
||||||
|
, _selector(std::move(selector)) {
|
||||||
|
resize(st::emojiPanWidth, st::emojiPanMaxHeight);
|
||||||
|
|
||||||
|
_selector->setParent(this);
|
||||||
|
_selector->setRoundRadius(0);
|
||||||
|
_selector->setGeometry(rect());
|
||||||
|
_selector->showStarted();
|
||||||
|
_selector->show();
|
||||||
|
connect(_selector, &TabbedSelector::cancelled, this, [this] {
|
||||||
|
if (_cancelledCallback) {
|
||||||
|
_cancelledCallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabbedSection::beforeHiding() {
|
||||||
|
_selector->beforeHiding();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabbedSection::afterShown() {
|
||||||
|
_selector->afterShown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabbedSection::resizeEvent(QResizeEvent *e) {
|
||||||
|
_selector->setGeometry(rect());
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<TabbedSelector> TabbedSection::takeSelector() {
|
||||||
|
return std::move(_selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointer<TabbedSelector> TabbedSection::getSelector() const {
|
||||||
|
return _selector.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabbedSection::stickersInstalled(uint64 setId) {
|
||||||
|
_selector->stickersInstalled(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -19,3 +19,40 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/twidget.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
class Controller;
|
||||||
|
} // namespace Window
|
||||||
|
|
||||||
|
namespace ChatHelpers {
|
||||||
|
|
||||||
|
class TabbedSelector;
|
||||||
|
|
||||||
|
class TabbedSection : public TWidget {
|
||||||
|
public:
|
||||||
|
TabbedSection(QWidget *parent, gsl::not_null<Window::Controller*> controller);
|
||||||
|
TabbedSection(QWidget *parent, gsl::not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector);
|
||||||
|
|
||||||
|
void beforeHiding();
|
||||||
|
void afterShown();
|
||||||
|
void setCancelledCallback(base::lambda<void()> callback) {
|
||||||
|
_cancelledCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<TabbedSelector> takeSelector();
|
||||||
|
QPointer<TabbedSelector> getSelector() const;
|
||||||
|
|
||||||
|
void stickersInstalled(uint64 setId);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
object_ptr<TabbedSelector> _selector;
|
||||||
|
base::lambda<void()> _cancelledCallback;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -292,28 +292,35 @@ TabbedSelector::TabbedSelector(QWidget *parent, gsl::not_null<Window::Controller
|
||||||
, _currentTabType(AuthSession::Current().data().emojiPanelTab()) {
|
, _currentTabType(AuthSession::Current().data().emojiPanelTab()) {
|
||||||
resize(st::emojiPanWidth, st::emojiPanMaxHeight);
|
resize(st::emojiPanWidth, st::emojiPanMaxHeight);
|
||||||
|
|
||||||
|
for (auto &tab : _tabs) {
|
||||||
|
tab.footer()->hide();
|
||||||
|
tab.widget()->hide();
|
||||||
|
}
|
||||||
|
|
||||||
createTabsSlider();
|
createTabsSlider();
|
||||||
|
|
||||||
_scroll->resize(st::emojiPanWidth - st::buttonRadius, height() - marginTop() - marginBottom());
|
_scroll->setGeometryToLeft(st::buttonRadius, marginTop(), st::emojiPanWidth - st::buttonRadius, height() - marginTop() - marginBottom());
|
||||||
_scroll->move(st::buttonRadius, marginTop());
|
|
||||||
setWidgetToScrollArea();
|
setWidgetToScrollArea();
|
||||||
|
|
||||||
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
||||||
|
|
||||||
for (auto &tab : _tabs) {
|
for (auto &tab : _tabs) {
|
||||||
connect(tab.widget(), &Inner::scrollToY, this, [this, tab = &tab](int y) {
|
auto widget = tab.widget();
|
||||||
|
connect(widget, &Inner::scrollToY, this, [this, tab = &tab](int y) {
|
||||||
if (tab == currentTab()) {
|
if (tab == currentTab()) {
|
||||||
scrollToY(y);
|
scrollToY(y);
|
||||||
} else {
|
} else {
|
||||||
tab->saveScrollTop(y);
|
tab->saveScrollTop(y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(tab.widget(), &Inner::disableScroll, this, [this, tab = &tab](bool disabled) {
|
connect(widget, &Inner::disableScroll, this, [this, tab = &tab](bool disabled) {
|
||||||
if (tab == currentTab()) {
|
if (tab == currentTab()) {
|
||||||
_scroll->disableScroll(disabled);
|
_scroll->disableScroll(disabled);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(tab.widget(), SIGNAL(saveConfigDelayed(int)), this, SLOT(onSaveConfigDelayed(int)));
|
connect(widget, &Inner::saveConfigDelayed, this, [this](int delay) {
|
||||||
|
AuthSession::Current().saveDataDelayed(delay);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(stickers(), SIGNAL(scrollUpdated()), this, SLOT(onScroll()));
|
connect(stickers(), SIGNAL(scrollUpdated()), this, SLOT(onScroll()));
|
||||||
|
@ -326,8 +333,6 @@ TabbedSelector::TabbedSelector(QWidget *parent, gsl::not_null<Window::Controller
|
||||||
connect(gifs(), SIGNAL(selected(InlineBots::Result*, UserData*)), this, SIGNAL(inlineResultSelected(InlineBots::Result*, UserData*)));
|
connect(gifs(), SIGNAL(selected(InlineBots::Result*, UserData*)), this, SIGNAL(inlineResultSelected(InlineBots::Result*, UserData*)));
|
||||||
connect(gifs(), SIGNAL(cancelled()), this, SIGNAL(cancelled()));
|
connect(gifs(), SIGNAL(cancelled()), this, SIGNAL(cancelled()));
|
||||||
|
|
||||||
_saveConfigTimer.setCallback([this] { Local::writeUserSettings(); });
|
|
||||||
|
|
||||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
}
|
}
|
||||||
|
@ -338,8 +343,7 @@ TabbedSelector::TabbedSelector(QWidget *parent, gsl::not_null<Window::Controller
|
||||||
|
|
||||||
// setAttribute(Qt::WA_AcceptTouchEvents);
|
// setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||||
|
showAll();
|
||||||
hideChildren();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
||||||
|
@ -363,10 +367,6 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::onSaveConfigDelayed(int delay) {
|
|
||||||
_saveConfigTimer.callOnce(delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TabbedSelector::paintEvent(QPaintEvent *e) {
|
void TabbedSelector::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ void TabbedSelector::switchTab() {
|
||||||
update();
|
update();
|
||||||
|
|
||||||
AuthSession::Current().data().setEmojiPanelTab(_currentTabType);
|
AuthSession::Current().data().setEmojiPanelTab(_currentTabType);
|
||||||
onSaveConfigDelayed(kSaveChosenTabTimeout);
|
AuthSession::Current().saveDataDelayed(kSaveChosenTabTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsl::not_null<EmojiListWidget*> TabbedSelector::emoji() const {
|
gsl::not_null<EmojiListWidget*> TabbedSelector::emoji() const {
|
||||||
|
|
|
@ -24,7 +24,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/effects/panel_animation.h"
|
#include "ui/effects/panel_animation.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "base/timer.h"
|
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
class Result;
|
class Result;
|
||||||
|
@ -79,8 +78,6 @@ protected:
|
||||||
private slots:
|
private slots:
|
||||||
void onScroll();
|
void onScroll();
|
||||||
|
|
||||||
void onSaveConfigDelayed(int delay);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void emojiSelected(EmojiPtr emoji);
|
void emojiSelected(EmojiPtr emoji);
|
||||||
void stickerSelected(DocumentData *sticker);
|
void stickerSelected(DocumentData *sticker);
|
||||||
|
@ -176,8 +173,6 @@ private:
|
||||||
std::array<Tab, Tab::kCount> _tabs;
|
std::array<Tab, Tab::kCount> _tabs;
|
||||||
TabType _currentTabType = TabType::Emoji;
|
TabType _currentTabType = TabType::Emoji;
|
||||||
|
|
||||||
base::Timer _saveConfigTimer;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TabbedSelector::Inner : public TWidget {
|
class TabbedSelector::Inner : public TWidget {
|
||||||
|
|
|
@ -74,7 +74,8 @@ struct DialogsInner::PeerSearchResult {
|
||||||
Dialogs::RippleRow row;
|
Dialogs::RippleRow row;
|
||||||
};
|
};
|
||||||
|
|
||||||
DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(parent)
|
DialogsInner::DialogsInner(QWidget *parent, gsl::not_null<Window::Controller*> controller, QWidget *main) : SplittedWidget(parent)
|
||||||
|
, _controller(controller)
|
||||||
, _dialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
, _dialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
||||||
, _contactsNoDialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contactsNoDialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
|
@ -1674,7 +1675,7 @@ void DialogsInner::refresh(bool toTop) {
|
||||||
emit mustScrollTo(0, 0);
|
emit mustScrollTo(0, 0);
|
||||||
loadPeerPhotos();
|
loadPeerPhotos();
|
||||||
}
|
}
|
||||||
Global::RefDialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
_controller->dialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1722,7 +1723,7 @@ void DialogsInner::searchInPeer(PeerData *peer) {
|
||||||
} else {
|
} else {
|
||||||
_cancelSearchInPeer->hide();
|
_cancelSearchInPeer->hide();
|
||||||
}
|
}
|
||||||
Global::RefDialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
_controller->dialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::clearFilter() {
|
void DialogsInner::clearFilter() {
|
||||||
|
@ -2274,7 +2275,7 @@ DialogsWidget::DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*>
|
||||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||||
, _lockUnlock(this, st::dialogsLock)
|
, _lockUnlock(this, st::dialogsLock)
|
||||||
, _scroll(this, st::dialogsScroll) {
|
, _scroll(this, st::dialogsScroll) {
|
||||||
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, parent));
|
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, _controller, parent));
|
||||||
connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
|
connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
|
||||||
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
|
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
|
||||||
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
|
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
|
||||||
|
|
|
@ -58,7 +58,7 @@ class DialogsInner : public Ui::SplittedWidget, public RPCSender, private base::
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DialogsInner(QWidget *parent, QWidget *main);
|
DialogsInner(QWidget *parent, gsl::not_null<Window::Controller*> controller, QWidget *main);
|
||||||
|
|
||||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
void addSavedPeersAfter(const QDateTime &date);
|
void addSavedPeersAfter(const QDateTime &date);
|
||||||
|
@ -226,6 +226,8 @@ private:
|
||||||
void savePinnedOrder();
|
void savePinnedOrder();
|
||||||
void step_pinnedShifting(TimeMs ms, bool timer);
|
void step_pinnedShifting(TimeMs ms, bool timer);
|
||||||
|
|
||||||
|
gsl::not_null<Window::Controller*> _controller;
|
||||||
|
|
||||||
DialogsList _dialogs;
|
DialogsList _dialogs;
|
||||||
DialogsList _dialogsImportant;
|
DialogsList _dialogsImportant;
|
||||||
|
|
||||||
|
|
|
@ -682,10 +682,6 @@ struct Data {
|
||||||
base::Observable<void> UnreadCounterUpdate;
|
base::Observable<void> UnreadCounterUpdate;
|
||||||
base::Observable<void> PeerChooseCancel;
|
base::Observable<void> PeerChooseCancel;
|
||||||
|
|
||||||
float64 DialogsWidthRatio = 5. / 14;
|
|
||||||
base::Variable<bool> DialogsListFocused = { false };
|
|
||||||
base::Variable<bool> DialogsListDisplayForced = { false };
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -805,8 +801,4 @@ DefineRefVar(Global, base::Observable<HistoryItem*>, ItemRemoved);
|
||||||
DefineRefVar(Global, base::Observable<void>, UnreadCounterUpdate);
|
DefineRefVar(Global, base::Observable<void>, UnreadCounterUpdate);
|
||||||
DefineRefVar(Global, base::Observable<void>, PeerChooseCancel);
|
DefineRefVar(Global, base::Observable<void>, PeerChooseCancel);
|
||||||
|
|
||||||
DefineVar(Global, float64, DialogsWidthRatio);
|
|
||||||
DefineRefVar(Global, base::Variable<bool>, DialogsListFocused);
|
|
||||||
DefineRefVar(Global, base::Variable<bool>, DialogsListDisplayForced);
|
|
||||||
|
|
||||||
} // namespace Global
|
} // namespace Global
|
||||||
|
|
|
@ -391,10 +391,6 @@ DeclareRefVar(base::Observable<HistoryItem*>, ItemRemoved);
|
||||||
DeclareRefVar(base::Observable<void>, UnreadCounterUpdate);
|
DeclareRefVar(base::Observable<void>, UnreadCounterUpdate);
|
||||||
DeclareRefVar(base::Observable<void>, PeerChooseCancel);
|
DeclareRefVar(base::Observable<void>, PeerChooseCancel);
|
||||||
|
|
||||||
DeclareVar(float64, DialogsWidthRatio);
|
|
||||||
DeclareRefVar(base::Variable<bool>, DialogsListFocused);
|
|
||||||
DeclareRefVar(base::Variable<bool>, DialogsListDisplayForced);
|
|
||||||
|
|
||||||
} // namespace Global
|
} // namespace Global
|
||||||
|
|
||||||
namespace Adaptive {
|
namespace Adaptive {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,8 @@ class TopBarWidget;
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
class TabbedPanel;
|
class TabbedPanel;
|
||||||
|
class TabbedSection;
|
||||||
|
class TabbedSelector;
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
||||||
class DragArea;
|
class DragArea;
|
||||||
|
@ -476,6 +478,11 @@ private:
|
||||||
|
|
||||||
void fullPeerUpdated(PeerData *peer);
|
void fullPeerUpdated(PeerData *peer);
|
||||||
void topBarClick();
|
void topBarClick();
|
||||||
|
void toggleTabbedSelectorMode();
|
||||||
|
void updateTabbedSelectorSectionShown();
|
||||||
|
void recountChatWidth();
|
||||||
|
int minimalWidthForTabbedSelectorSection() const;
|
||||||
|
void setReportSpamStatus(DBIPeerReportSpamStatus status);
|
||||||
|
|
||||||
void animationCallback();
|
void animationCallback();
|
||||||
void updateOverStates(QPoint pos);
|
void updateOverStates(QPoint pos);
|
||||||
|
@ -529,6 +536,7 @@ private:
|
||||||
int _replyToNameVersion = 0;
|
int _replyToNameVersion = 0;
|
||||||
void updateReplyToName();
|
void updateReplyToName();
|
||||||
|
|
||||||
|
int _chatWidth = 0;
|
||||||
MsgId _editMsgId = 0;
|
MsgId _editMsgId = 0;
|
||||||
|
|
||||||
HistoryItem *_replyEditMsg = nullptr;
|
HistoryItem *_replyEditMsg = nullptr;
|
||||||
|
@ -739,7 +747,7 @@ private:
|
||||||
bool showRecordButton() const;
|
bool showRecordButton() const;
|
||||||
bool showInlineBotCancel() const;
|
bool showInlineBotCancel() const;
|
||||||
|
|
||||||
object_ptr<ReportSpamPanel> _reportSpamPanel;
|
object_ptr<ReportSpamPanel> _reportSpamPanel = { nullptr };
|
||||||
|
|
||||||
object_ptr<Ui::SendButton> _send;
|
object_ptr<Ui::SendButton> _send;
|
||||||
object_ptr<Ui::FlatButton> _unblock;
|
object_ptr<Ui::FlatButton> _unblock;
|
||||||
|
@ -749,7 +757,7 @@ private:
|
||||||
mtpRequestId _unblockRequest = 0;
|
mtpRequestId _unblockRequest = 0;
|
||||||
mtpRequestId _reportSpamRequest = 0;
|
mtpRequestId _reportSpamRequest = 0;
|
||||||
object_ptr<Ui::IconButton> _attachToggle;
|
object_ptr<Ui::IconButton> _attachToggle;
|
||||||
object_ptr<Ui::EmojiButton> _attachEmoji;
|
object_ptr<Ui::EmojiButton> _tabbedSelectorToggle;
|
||||||
object_ptr<Ui::IconButton> _botKeyboardShow;
|
object_ptr<Ui::IconButton> _botKeyboardShow;
|
||||||
object_ptr<Ui::IconButton> _botKeyboardHide;
|
object_ptr<Ui::IconButton> _botKeyboardHide;
|
||||||
object_ptr<Ui::IconButton> _botCommandStart;
|
object_ptr<Ui::IconButton> _botCommandStart;
|
||||||
|
@ -781,6 +789,8 @@ private:
|
||||||
|
|
||||||
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
|
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
|
||||||
object_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
|
object_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
|
||||||
|
object_ptr<ChatHelpers::TabbedSection> _tabbedSection = { nullptr };
|
||||||
|
QPointer<ChatHelpers::TabbedSelector> _tabbedSelector;
|
||||||
DragState _attachDrag = DragStateNone;
|
DragState _attachDrag = DragStateNone;
|
||||||
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
|
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
|
||||||
|
|
||||||
|
@ -814,6 +824,7 @@ 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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,7 +121,6 @@ void Widget::changeLanguage(int32 languageId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setInnerFocus() {
|
void Widget::setInnerFocus() {
|
||||||
Global::RefDialogsListFocused().set(false, true);
|
|
||||||
if (getStep()->animating()) {
|
if (getStep()->animating()) {
|
||||||
setFocus();
|
setFocus();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -113,12 +113,15 @@ MainWidget::MainWidget(QWidget *parent, gsl::not_null<Window::Controller*> contr
|
||||||
subscribe(AuthSession::Current().api().fullPeerUpdated(), [this](PeerData *peer) {
|
subscribe(AuthSession::Current().api().fullPeerUpdated(), [this](PeerData *peer) {
|
||||||
emit peerUpdated(peer);
|
emit peerUpdated(peer);
|
||||||
});
|
});
|
||||||
subscribe(Global::RefDialogsListFocused(), [this](bool) {
|
subscribe(_controller->dialogsListFocused(), [this](bool) {
|
||||||
updateDialogsWidthAnimated();
|
updateDialogsWidthAnimated();
|
||||||
});
|
});
|
||||||
subscribe(Global::RefDialogsListDisplayForced(), [this](bool) {
|
subscribe(_controller->dialogsListDisplayForced(), [this](bool) {
|
||||||
updateDialogsWidthAnimated();
|
updateDialogsWidthAnimated();
|
||||||
});
|
});
|
||||||
|
subscribe(_controller->dialogsWidthRatio(), [this](float64) {
|
||||||
|
updateControlsGeometry();
|
||||||
|
});
|
||||||
|
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
|
|
||||||
|
@ -2141,7 +2144,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::RefDialogsListFocused().set(false, true);
|
_controller->dialogsListFocused().set(false, true);
|
||||||
_a_dialogsWidth.finish();
|
_a_dialogsWidth.finish();
|
||||||
|
|
||||||
bool back = (way == Ui::ShowWay::Backward || !peerId);
|
bool back = (way == Ui::ShowWay::Backward || !peerId);
|
||||||
|
@ -2348,7 +2351,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::RefDialogsListFocused().set(false, true);
|
_controller->dialogsListFocused().set(false, true);
|
||||||
_a_dialogsWidth.finish();
|
_a_dialogsWidth.finish();
|
||||||
|
|
||||||
auto animatedShow = [this] {
|
auto animatedShow = [this] {
|
||||||
|
@ -2411,9 +2414,10 @@ void MainWidget::showWideSection(const Window::SectionMemento &memento) {
|
||||||
showNewWideSection(&memento, false, true);
|
showNewWideSection(&memento, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarShadow) {
|
Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection) {
|
||||||
Window::SectionSlideParams result;
|
Window::SectionSlideParams result;
|
||||||
result.withTopBarShadow = willHaveTopBarShadow;
|
result.withTopBarShadow = willHaveTopBarShadow;
|
||||||
|
result.withTabbedSection = willHaveTabbedSection;
|
||||||
if (selectingPeer() && Adaptive::OneColumn()) {
|
if (selectingPeer() && Adaptive::OneColumn()) {
|
||||||
result.withTopBarShadow = false;
|
result.withTopBarShadow = false;
|
||||||
} else if (_wideSection) {
|
} else if (_wideSection) {
|
||||||
|
@ -2423,6 +2427,9 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarS
|
||||||
} else if (!_overview && !_history->peer()) {
|
} else if (!_overview && !_history->peer()) {
|
||||||
result.withTopBarShadow = false;
|
result.withTopBarShadow = false;
|
||||||
}
|
}
|
||||||
|
if ((selectingPeer() && Adaptive::OneColumn()) || !_history->peer()) {
|
||||||
|
result.withTabbedSection = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_player) {
|
if (_player) {
|
||||||
_player->hideShadow();
|
_player->hideShadow();
|
||||||
|
@ -2480,25 +2487,25 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarS
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams MainWidget::prepareWideSectionAnimation(Window::SectionWidget *section) {
|
Window::SectionSlideParams MainWidget::prepareWideSectionAnimation(Window::SectionWidget *section) {
|
||||||
return prepareShowAnimation(section->hasTopBarShadow());
|
return prepareShowAnimation(section->hasTopBarShadow(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams MainWidget::prepareHistoryAnimation(PeerId historyPeerId) {
|
Window::SectionSlideParams MainWidget::prepareHistoryAnimation(PeerId historyPeerId) {
|
||||||
return prepareShowAnimation(historyPeerId != 0);
|
return prepareShowAnimation(historyPeerId != 0, historyPeerId != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams MainWidget::prepareOverviewAnimation() {
|
Window::SectionSlideParams MainWidget::prepareOverviewAnimation() {
|
||||||
return prepareShowAnimation(true);
|
return prepareShowAnimation(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams MainWidget::prepareDialogsAnimation() {
|
Window::SectionSlideParams MainWidget::prepareDialogsAnimation() {
|
||||||
return prepareShowAnimation(false);
|
return prepareShowAnimation(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack) {
|
void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack) {
|
||||||
QPixmap animCache;
|
QPixmap animCache;
|
||||||
|
|
||||||
Global::RefDialogsListFocused().set(false, true);
|
_controller->dialogsListFocused().set(false, true);
|
||||||
_a_dialogsWidth.finish();
|
_a_dialogsWidth.finish();
|
||||||
|
|
||||||
auto newWideGeometry = QRect(_history->x(), _playerHeight, _history->width(), height() - _playerHeight);
|
auto newWideGeometry = QRect(_history->x(), _playerHeight, _history->width(), height() - _playerHeight);
|
||||||
|
@ -3058,22 +3065,21 @@ bool MainWidget::eventFilter(QObject *o, QEvent *e) {
|
||||||
} else if (e->type() == QEvent::MouseButtonRelease) {
|
} else if (e->type() == QEvent::MouseButtonRelease) {
|
||||||
_resizingSide = false;
|
_resizingSide = false;
|
||||||
if (!Adaptive::OneColumn()) {
|
if (!Adaptive::OneColumn()) {
|
||||||
Global::SetDialogsWidthRatio(float64(_dialogsWidth) / width());
|
_controller->dialogsWidthRatio().set(float64(_dialogsWidth) / width(), true);
|
||||||
}
|
}
|
||||||
Local::writeUserSettings();
|
Local::writeUserSettings();
|
||||||
} else if (e->type() == QEvent::MouseMove && _resizingSide) {
|
} else if (e->type() == QEvent::MouseMove && _resizingSide) {
|
||||||
auto newWidth = mouseLeft() - _resizingSideShift;
|
auto newWidth = mouseLeft() - _resizingSideShift;
|
||||||
Global::SetDialogsWidthRatio(float64(newWidth) / width());
|
_controller->dialogsWidthRatio().set(float64(newWidth) / width(), true);
|
||||||
updateControlsGeometry();
|
|
||||||
}
|
}
|
||||||
} else if (e->type() == QEvent::FocusIn) {
|
} else if (e->type() == QEvent::FocusIn) {
|
||||||
if (auto widget = qobject_cast<QWidget*>(o)) {
|
if (auto widget = qobject_cast<QWidget*>(o)) {
|
||||||
if (_history == widget || _history->isAncestorOf(widget)
|
if (_history == widget || _history->isAncestorOf(widget)
|
||||||
|| (_overview && (_overview == widget || _overview->isAncestorOf(widget)))
|
|| (_overview && (_overview == widget || _overview->isAncestorOf(widget)))
|
||||||
|| (_wideSection && (_wideSection == widget || _wideSection->isAncestorOf(widget)))) {
|
|| (_wideSection && (_wideSection == widget || _wideSection->isAncestorOf(widget)))) {
|
||||||
Global::RefDialogsListFocused().set(false, false);
|
_controller->dialogsListFocused().set(false);
|
||||||
} else if (_dialogs == widget || _dialogs->isAncestorOf(widget)) {
|
} else if (_dialogs == widget || _dialogs->isAncestorOf(widget)) {
|
||||||
Global::RefDialogsListFocused().set(true, false);
|
_controller->dialogsListFocused().set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (e->type() == QEvent::MouseButtonPress) {
|
} else if (e->type() == QEvent::MouseButtonPress) {
|
||||||
|
@ -3094,62 +3100,14 @@ void MainWidget::handleAdaptiveLayoutUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateWindowAdaptiveLayout() {
|
void MainWidget::updateWindowAdaptiveLayout() {
|
||||||
auto layout = Adaptive::WindowLayout::OneColumn;
|
auto layout = _controller->computeColumnLayout();
|
||||||
|
_dialogsWidth = layout.dialogsWidth;
|
||||||
auto dialogsWidth = qRound(width() * Global::DialogsWidthRatio());
|
if (layout.windowLayout != Global::AdaptiveWindowLayout()) {
|
||||||
auto historyWidth = width() - dialogsWidth;
|
Global::SetAdaptiveWindowLayout(layout.windowLayout);
|
||||||
accumulate_max(historyWidth, st::windowMinWidth);
|
|
||||||
dialogsWidth = width() - historyWidth;
|
|
||||||
|
|
||||||
auto useOneColumnLayout = [this, dialogsWidth] {
|
|
||||||
auto someSectionShown = !selectingPeer() && isSectionShown();
|
|
||||||
if (dialogsWidth < st::dialogsPadding.x() && (Adaptive::OneColumn() || someSectionShown)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (width() < st::windowMinWidth + st::dialogsWidthMin) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
auto useSmallColumnLayout = [this, dialogsWidth] {
|
|
||||||
// used if useOneColumnLayout() == false.
|
|
||||||
if (dialogsWidth < st::dialogsWidthMin / 2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if (useOneColumnLayout()) {
|
|
||||||
dialogsWidth = width();
|
|
||||||
} else if (useSmallColumnLayout()) {
|
|
||||||
layout = Adaptive::WindowLayout::SmallColumn;
|
|
||||||
auto forceWideDialogs = [this] {
|
|
||||||
if (Global::DialogsListDisplayForced().value()) {
|
|
||||||
return true;
|
|
||||||
} else if (Global::DialogsListFocused().value()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !isSectionShown();
|
|
||||||
};
|
|
||||||
if (forceWideDialogs()) {
|
|
||||||
dialogsWidth = st::dialogsWidthMin;
|
|
||||||
} else {
|
|
||||||
dialogsWidth = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
layout = Adaptive::WindowLayout::Normal;
|
|
||||||
accumulate_max(dialogsWidth, st::dialogsWidthMin);
|
|
||||||
}
|
|
||||||
_dialogsWidth = dialogsWidth;
|
|
||||||
if (layout != Global::AdaptiveWindowLayout()) {
|
|
||||||
Global::SetAdaptiveWindowLayout(layout);
|
|
||||||
Adaptive::Changed().notify(true);
|
Adaptive::Changed().notify(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::needBackButton() {
|
|
||||||
return isSectionShown();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
bool MainWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
||||||
if (_overview) {
|
if (_overview) {
|
||||||
return _overview->paintTopBar(p, decreaseWidth);
|
return _overview->paintTopBar(p, decreaseWidth);
|
||||||
|
|
|
@ -144,7 +144,7 @@ class MainWidget : public TWidget, public RPCSender, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
MainWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
|
MainWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
|
||||||
|
|
||||||
bool needBackButton();
|
bool isSectionShown() 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);
|
||||||
|
@ -481,9 +481,8 @@ private:
|
||||||
void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req);
|
void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
void mediaOverviewUpdated(const Notify::PeerUpdate &update);
|
void mediaOverviewUpdated(const Notify::PeerUpdate &update);
|
||||||
|
|
||||||
Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow);
|
Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection);
|
||||||
void showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack);
|
void showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack);
|
||||||
bool isSectionShown() const;
|
|
||||||
|
|
||||||
// All this methods use the prepareShowAnimation().
|
// All this methods use the prepareShowAnimation().
|
||||||
Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section);
|
Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section);
|
||||||
|
|
|
@ -110,15 +110,25 @@ MainWindow::MainWindow() {
|
||||||
|
|
||||||
connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock()));
|
connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock()));
|
||||||
|
|
||||||
subscribe(Global::RefSelfChanged(), [this]() { updateGlobalMenu(); });
|
subscribe(Global::RefSelfChanged(), [this] { updateGlobalMenu(); });
|
||||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
||||||
themeUpdated(data);
|
themeUpdated(data);
|
||||||
});
|
});
|
||||||
|
subscribe(Messenger::Instance().authSessionChanged(), [this] { checkAuthSession(); });
|
||||||
|
checkAuthSession();
|
||||||
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::checkAuthSession() {
|
||||||
|
if (AuthSession::Exists()) {
|
||||||
|
_controller = std::make_unique<Window::Controller>(this);
|
||||||
|
} else {
|
||||||
|
_controller = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::inactivePress(bool inactive) {
|
void MainWindow::inactivePress(bool inactive) {
|
||||||
_inactivePress = inactive;
|
_inactivePress = inactive;
|
||||||
if (_inactivePress) {
|
if (_inactivePress) {
|
||||||
|
@ -200,7 +210,6 @@ void MainWindow::clearWidgetsHook() {
|
||||||
auto wasMain = (_main != nullptr);
|
auto wasMain = (_main != nullptr);
|
||||||
_passcode.destroyDelayed();
|
_passcode.destroyDelayed();
|
||||||
_main.destroy();
|
_main.destroy();
|
||||||
_controller.reset();
|
|
||||||
_intro.destroy();
|
_intro.destroy();
|
||||||
if (wasMain) {
|
if (wasMain) {
|
||||||
App::clearHistories();
|
App::clearHistories();
|
||||||
|
@ -352,7 +361,7 @@ void MainWindow::setupMain(const MTPUser *self) {
|
||||||
|
|
||||||
t_assert(AuthSession::Exists());
|
t_assert(AuthSession::Exists());
|
||||||
|
|
||||||
_controller = std::make_unique<Window::Controller>(this);
|
|
||||||
_main.create(bodyWidget(), controller());
|
_main.create(bodyWidget(), controller());
|
||||||
_main->show();
|
_main->show();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
|
@ -199,6 +199,7 @@ private slots:
|
||||||
void onWindowActiveChanged();
|
void onWindowActiveChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void checkAuthSession();
|
||||||
void showConnecting(const QString &text, const QString &reconnect = QString());
|
void showConnecting(const QString &text, const QString &reconnect = QString());
|
||||||
void hideConnecting();
|
void hideConnecting();
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ MediaView::MediaView(QWidget*) : TWidget(nullptr)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
subscribe(Messenger::Instance().authSessionChanged(), [this, subscribeToDownloadFinished] {
|
subscribe(Messenger::Instance().authSessionChanged(), [subscribeToDownloadFinished] {
|
||||||
subscribeToDownloadFinished();
|
subscribeToDownloadFinished();
|
||||||
});
|
});
|
||||||
subscribeToDownloadFinished();
|
subscribeToDownloadFinished();
|
||||||
|
|
|
@ -38,6 +38,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "storage/serialize_common.h"
|
#include "storage/serialize_common.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ Messenger *Messenger::InstancePointer() {
|
||||||
|
|
||||||
struct Messenger::Private {
|
struct Messenger::Private {
|
||||||
UserId authSessionUserId = 0;
|
UserId authSessionUserId = 0;
|
||||||
std::unique_ptr<AuthSessionData> authSessionData;
|
std::unique_ptr<Local::StoredAuthSession> storedAuthSession;
|
||||||
MTP::Instance::Config mtpConfig;
|
MTP::Instance::Config mtpConfig;
|
||||||
MTP::AuthKeysList mtpKeysToDestroy;
|
MTP::AuthKeysList mtpKeysToDestroy;
|
||||||
};
|
};
|
||||||
|
@ -220,14 +221,14 @@ void Messenger::setAuthSessionUserId(UserId userId) {
|
||||||
_private->authSessionUserId = userId;
|
_private->authSessionUserId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::setAuthSessionData(std::unique_ptr<AuthSessionData> data) {
|
void Messenger::setAuthSessionFromStorage(std::unique_ptr<Local::StoredAuthSession> data) {
|
||||||
Expects(!authSession());
|
Expects(!authSession());
|
||||||
_private->authSessionData = std::move(data);
|
_private->storedAuthSession = std::move(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthSessionData *Messenger::getAuthSessionData() {
|
AuthSessionData *Messenger::getAuthSessionData() {
|
||||||
if (_private->authSessionUserId) {
|
if (_private->authSessionUserId) {
|
||||||
return _private->authSessionData.get();
|
return _private->storedAuthSession ? &_private->storedAuthSession->data : nullptr;
|
||||||
} else if (AuthSession::Exists()) {
|
} else if (AuthSession::Exists()) {
|
||||||
return &AuthSession::Current().data();
|
return &AuthSession::Current().data();
|
||||||
}
|
}
|
||||||
|
@ -301,11 +302,15 @@ void Messenger::startMtp() {
|
||||||
if (_private->authSessionUserId) {
|
if (_private->authSessionUserId) {
|
||||||
authSessionCreate(base::take(_private->authSessionUserId));
|
authSessionCreate(base::take(_private->authSessionUserId));
|
||||||
}
|
}
|
||||||
if (_private->authSessionData) {
|
if (_private->storedAuthSession) {
|
||||||
if (_authSession) {
|
if (_authSession) {
|
||||||
_authSession->data().copyFrom(*_private->authSessionData);
|
_authSession->data().copyFrom(_private->storedAuthSession->data);
|
||||||
|
if (auto window = App::wnd()) {
|
||||||
|
t_assert(window->controller() != nullptr);
|
||||||
|
window->controller()->dialogsWidthRatio().set(_private->storedAuthSession->dialogsWidthRatio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_private->authSessionData.reset();
|
_private->storedAuthSession.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,14 +618,14 @@ void Messenger::onSwitchTestMode() {
|
||||||
void Messenger::authSessionCreate(UserId userId) {
|
void Messenger::authSessionCreate(UserId userId) {
|
||||||
Expects(_mtproto != nullptr);
|
Expects(_mtproto != nullptr);
|
||||||
_authSession = std::make_unique<AuthSession>(userId);
|
_authSession = std::make_unique<AuthSession>(userId);
|
||||||
authSessionChanged().notify();
|
authSessionChanged().notify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::authSessionDestroy() {
|
void Messenger::authSessionDestroy() {
|
||||||
_authSession.reset();
|
_authSession.reset();
|
||||||
_private->authSessionData.reset();
|
_private->storedAuthSession.reset();
|
||||||
_private->authSessionUserId = 0;
|
_private->authSessionUserId = 0;
|
||||||
authSessionChanged().notify();
|
authSessionChanged().notify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::setInternalLinkDomain(const QString &domain) const {
|
void Messenger::setInternalLinkDomain(const QString &domain) const {
|
||||||
|
|
|
@ -33,6 +33,10 @@ class MainWidget;
|
||||||
class FileUploader;
|
class FileUploader;
|
||||||
class Translator;
|
class Translator;
|
||||||
|
|
||||||
|
namespace Local {
|
||||||
|
struct StoredAuthSession;
|
||||||
|
} // namespace Local
|
||||||
|
|
||||||
class Messenger final : public QObject, public RPCSender, private base::Subscriber {
|
class Messenger final : public QObject, public RPCSender, private base::Subscriber {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -62,7 +66,7 @@ public:
|
||||||
void setMtpMainDcId(MTP::DcId mainDcId);
|
void setMtpMainDcId(MTP::DcId mainDcId);
|
||||||
void setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData);
|
void setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData);
|
||||||
void setAuthSessionUserId(UserId userId);
|
void setAuthSessionUserId(UserId userId);
|
||||||
void setAuthSessionData(std::unique_ptr<AuthSessionData> data);
|
void setAuthSessionFromStorage(std::unique_ptr<Local::StoredAuthSession> data);
|
||||||
AuthSessionData *getAuthSessionData();
|
AuthSessionData *getAuthSessionData();
|
||||||
|
|
||||||
// Serialization.
|
// Serialization.
|
||||||
|
|
|
@ -29,6 +29,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
|
||||||
PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
|
PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
|
||||||
|
@ -187,6 +188,8 @@ void PasscodeWidget::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PasscodeWidget::setInnerFocus() {
|
void PasscodeWidget::setInnerFocus() {
|
||||||
Global::RefDialogsListFocused().set(false, true);
|
if (auto controller = App::wnd()->controller()) {
|
||||||
|
controller->dialogsListFocused().set(false, true);
|
||||||
|
}
|
||||||
_passcode->setFocusFast();
|
_passcode->setFocusFast();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
@ -638,12 +639,12 @@ enum class WriteMapWhen {
|
||||||
Soon,
|
Soon,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<AuthSessionData> AuthSessionDataCache;
|
std::unique_ptr<StoredAuthSession> StoredAuthSessionCache;
|
||||||
AuthSessionData &GetAuthSessionDataCache() {
|
StoredAuthSession &GetStoredAuthSessionCache() {
|
||||||
if (!AuthSessionDataCache) {
|
if (!StoredAuthSessionCache) {
|
||||||
AuthSessionDataCache = std::make_unique<AuthSessionData>();
|
StoredAuthSessionCache = std::make_unique<StoredAuthSession>();
|
||||||
}
|
}
|
||||||
return *AuthSessionDataCache;
|
return *StoredAuthSessionCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _writeMap(WriteMapWhen when = WriteMapWhen::Soon);
|
void _writeMap(WriteMapWhen when = WriteMapWhen::Soon);
|
||||||
|
@ -1010,7 +1011,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
Global::SetDialogsModeEnabled(enabled == 1);
|
Global::SetDialogsModeEnabled(enabled == 1);
|
||||||
Dialogs::Mode mode = Dialogs::Mode::All;
|
auto mode = Dialogs::Mode::All;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
mode = static_cast<Dialogs::Mode>(modeInt);
|
mode = static_cast<Dialogs::Mode>(modeInt);
|
||||||
if (mode != Dialogs::Mode::All && mode != Dialogs::Mode::Important) {
|
if (mode != Dialogs::Mode::All && mode != Dialogs::Mode::Important) {
|
||||||
|
@ -1086,7 +1087,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||||
stream >> v;
|
stream >> v;
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
Global::SetDialogsWidthRatio(v / 1000000.);
|
GetStoredAuthSessionCache().dialogsWidthRatio = v / 1000000.;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiLastSeenWarningSeenOld: {
|
case dbiLastSeenWarningSeenOld: {
|
||||||
|
@ -1094,7 +1095,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||||
stream >> v;
|
stream >> v;
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
GetAuthSessionDataCache().setLastSeenWarningSeen(v == 1);
|
GetStoredAuthSessionCache().data.setLastSeenWarningSeen(v == 1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiAuthSessionData: {
|
case dbiAuthSessionData: {
|
||||||
|
@ -1102,7 +1103,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||||
stream >> v;
|
stream >> v;
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
GetAuthSessionDataCache().constructFromSerialized(v);
|
GetStoredAuthSessionCache().data.constructFromSerialized(v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiWorkMode: {
|
case dbiWorkMode: {
|
||||||
|
@ -1707,8 +1708,9 @@ void _writeUserSettings() {
|
||||||
recentEmojiPreloadData.push_back(qMakePair(item.first->id(), item.second));
|
recentEmojiPreloadData.push_back(qMakePair(item.first->id(), item.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto userDataInstance = AuthSessionDataCache ? AuthSessionDataCache.get() : Messenger::Instance().getAuthSessionData();
|
auto userDataInstance = StoredAuthSessionCache ? &StoredAuthSessionCache->data : Messenger::Instance().getAuthSessionData();
|
||||||
auto userData = userDataInstance ? userDataInstance->serialize() : QByteArray();
|
auto userData = userDataInstance ? userDataInstance->serialize() : QByteArray();
|
||||||
|
auto dialogsWidthRatio = StoredAuthSessionCache ? StoredAuthSessionCache->dialogsWidthRatio : (App::wnd() ? App::wnd()->controller()->dialogsWidthRatio().value() : Window::Controller::kDefaultDialogsWidthRatio);
|
||||||
|
|
||||||
uint32 size = 21 * (sizeof(quint32) + sizeof(qint32));
|
uint32 size = 21 * (sizeof(quint32) + sizeof(qint32));
|
||||||
size += sizeof(quint32) + Serialize::stringSize(Global::AskDownloadPath() ? QString() : Global::DownloadPath()) + Serialize::bytearraySize(Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
size += sizeof(quint32) + Serialize::stringSize(Global::AskDownloadPath() ? QString() : Global::DownloadPath()) + Serialize::bytearraySize(Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
||||||
|
@ -1753,7 +1755,7 @@ void _writeUserSettings() {
|
||||||
data.stream << quint32(dbiDialogsMode) << qint32(Global::DialogsModeEnabled() ? 1 : 0) << static_cast<qint32>(Global::DialogsMode());
|
data.stream << quint32(dbiDialogsMode) << qint32(Global::DialogsModeEnabled() ? 1 : 0) << static_cast<qint32>(Global::DialogsMode());
|
||||||
data.stream << quint32(dbiModerateMode) << qint32(Global::ModerateModeEnabled() ? 1 : 0);
|
data.stream << quint32(dbiModerateMode) << qint32(Global::ModerateModeEnabled() ? 1 : 0);
|
||||||
data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0);
|
data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0);
|
||||||
data.stream << quint32(dbiDialogsWidthRatio) << qint32(snap(qRound(Global::DialogsWidthRatio() * 1000000), 0, 1000000));
|
data.stream << quint32(dbiDialogsWidthRatio) << qint32(snap(qRound(dialogsWidthRatio * 1000000), 0, 1000000));
|
||||||
data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer());
|
data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer());
|
||||||
if (!userData.isEmpty()) {
|
if (!userData.isEmpty()) {
|
||||||
data.stream << quint32(dbiAuthSessionData) << userData;
|
data.stream << quint32(dbiAuthSessionData) << userData;
|
||||||
|
@ -2063,7 +2065,7 @@ ReadMapState _readMap(const QByteArray &pass) {
|
||||||
_readUserSettings();
|
_readUserSettings();
|
||||||
_readMtpData();
|
_readMtpData();
|
||||||
|
|
||||||
Messenger::Instance().setAuthSessionData(std::move(AuthSessionDataCache));
|
Messenger::Instance().setAuthSessionFromStorage(std::move(StoredAuthSessionCache));
|
||||||
|
|
||||||
LOG(("Map read time: %1").arg(getms() - ms));
|
LOG(("Map read time: %1").arg(getms() - ms));
|
||||||
if (_oldSettingsVersion < AppVersion) {
|
if (_oldSettingsVersion < AppVersion) {
|
||||||
|
@ -2360,7 +2362,7 @@ void reset() {
|
||||||
_savedGifsKey = 0;
|
_savedGifsKey = 0;
|
||||||
_backgroundKey = _userSettingsKey = _recentHashtagsAndBotsKey = _savedPeersKey = 0;
|
_backgroundKey = _userSettingsKey = _recentHashtagsAndBotsKey = _savedPeersKey = 0;
|
||||||
_oldMapVersion = _oldSettingsVersion = 0;
|
_oldMapVersion = _oldSettingsVersion = 0;
|
||||||
AuthSessionDataCache.reset();
|
StoredAuthSessionCache.reset();
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
_writeMap(WriteMapWhen::Now);
|
_writeMap(WriteMapWhen::Now);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/basic_types.h"
|
#include "core/basic_types.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
|
#include "auth_session.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
|
@ -31,6 +32,11 @@ struct Cached;
|
||||||
|
|
||||||
namespace Local {
|
namespace Local {
|
||||||
|
|
||||||
|
struct StoredAuthSession {
|
||||||
|
AuthSessionData data;
|
||||||
|
float64 dialogsWidthRatio;
|
||||||
|
};
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
|
|
|
@ -339,17 +339,24 @@ void MainWindow::showRightColumn(object_ptr<TWidget> widget) {
|
||||||
}
|
}
|
||||||
auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0;
|
auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0;
|
||||||
setMinimumWidth(st::windowMinWidth + nowRightWidth);
|
setMinimumWidth(st::windowMinWidth + nowRightWidth);
|
||||||
auto nowWidth = width();
|
|
||||||
|
|
||||||
if (!isMaximized()) {
|
if (!isMaximized()) {
|
||||||
auto desktop = QDesktopWidget().availableGeometry(this);
|
tryToExtendWidthBy(wasWidth + nowRightWidth - wasRightWidth - width());
|
||||||
auto newWidth = qMin(wasWidth + nowRightWidth - wasRightWidth, desktop.width());
|
} else {
|
||||||
auto newLeft = qMin(x(), desktop.x() + desktop.width() - newWidth);
|
updateControlsGeometry();
|
||||||
if (x() != newLeft || width() != newWidth) {
|
}
|
||||||
setGeometry(newLeft, y(), newWidth, height());
|
}
|
||||||
} else {
|
|
||||||
updateControlsGeometry();
|
bool MainWindow::canExtendWidthBy(int addToWidth) {
|
||||||
}
|
auto desktop = QDesktopWidget().availableGeometry(this);
|
||||||
|
return (width() + addToWidth) <= desktop.width();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::tryToExtendWidthBy(int addToWidth) {
|
||||||
|
auto desktop = QDesktopWidget().availableGeometry(this);
|
||||||
|
auto newWidth = qMin(width() + addToWidth, desktop.width());
|
||||||
|
auto newLeft = qMin(x(), desktop.x() + desktop.width() - newWidth);
|
||||||
|
if (x() != newLeft || width() != newWidth) {
|
||||||
|
setGeometry(newLeft, y(), newWidth, height());
|
||||||
} else {
|
} else {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ public:
|
||||||
QWidget *filedialogParent();
|
QWidget *filedialogParent();
|
||||||
|
|
||||||
void showRightColumn(object_ptr<TWidget> widget);
|
void showRightColumn(object_ptr<TWidget> widget);
|
||||||
|
bool canExtendWidthBy(int addToWidth);
|
||||||
|
void tryToExtendWidthBy(int addToWidth);
|
||||||
|
|
||||||
virtual void updateTrayMenu(bool force = false) {
|
virtual void updateTrayMenu(bool force = false) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ 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();
|
||||||
|
|
|
@ -21,6 +21,9 @@ 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 "mainwidget.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
|
@ -50,4 +53,74 @@ bool Controller::isGifPausedAtLeastFor(GifPauseReason reason) const {
|
||||||
return (static_cast<int>(_gifPauseReasons) >= 2 * static_cast<int>(reason)) || !window()->isActive();
|
return (static_cast<int>(_gifPauseReasons) >= 2 * static_cast<int>(reason)) || !window()->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controller::ColumnLayout Controller::computeColumnLayout() {
|
||||||
|
auto layout = Adaptive::WindowLayout::OneColumn;
|
||||||
|
|
||||||
|
auto bodyWidth = window()->bodyWidget()->width();
|
||||||
|
auto dialogsWidth = qRound(bodyWidth * dialogsWidthRatio().value());
|
||||||
|
auto historyWidth = bodyWidth - dialogsWidth;
|
||||||
|
accumulate_max(historyWidth, st::windowMinWidth);
|
||||||
|
dialogsWidth = bodyWidth - historyWidth;
|
||||||
|
|
||||||
|
auto useOneColumnLayout = [this, bodyWidth, dialogsWidth] {
|
||||||
|
auto someSectionShown = !App::main()->selectingPeer() && App::main()->isSectionShown();
|
||||||
|
if (dialogsWidth < st::dialogsPadding.x() && (Adaptive::OneColumn() || someSectionShown)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bodyWidth < st::windowMinWidth + st::dialogsWidthMin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
auto useSmallColumnLayout = [this, dialogsWidth] {
|
||||||
|
// used if useOneColumnLayout() == false.
|
||||||
|
if (dialogsWidth < st::dialogsWidthMin / 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (useOneColumnLayout()) {
|
||||||
|
dialogsWidth = bodyWidth;
|
||||||
|
} else if (useSmallColumnLayout()) {
|
||||||
|
layout = Adaptive::WindowLayout::SmallColumn;
|
||||||
|
auto forceWideDialogs = [this] {
|
||||||
|
if (dialogsListDisplayForced().value()) {
|
||||||
|
return true;
|
||||||
|
} else if (dialogsListFocused().value()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !App::main()->isSectionShown();
|
||||||
|
};
|
||||||
|
if (forceWideDialogs()) {
|
||||||
|
dialogsWidth = st::dialogsWidthMin;
|
||||||
|
} else {
|
||||||
|
dialogsWidth = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
layout = Adaptive::WindowLayout::Normal;
|
||||||
|
accumulate_max(dialogsWidth, st::dialogsWidthMin);
|
||||||
|
}
|
||||||
|
return { bodyWidth, dialogsWidth, layout };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::provideChatWidth(int requestedWidth) {
|
||||||
|
auto currentLayout = computeColumnLayout();
|
||||||
|
auto chatWidth = currentLayout.bodyWidth - currentLayout.dialogsWidth;
|
||||||
|
if (currentLayout.windowLayout == Adaptive::WindowLayout::OneColumn) {
|
||||||
|
chatWidth = currentLayout.bodyWidth;
|
||||||
|
}
|
||||||
|
if (chatWidth >= requestedWidth) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!window()->canExtendWidthBy(requestedWidth - chatWidth)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
window()->tryToExtendWidthBy(requestedWidth - chatWidth);
|
||||||
|
auto newLayout = computeColumnLayout();
|
||||||
|
if (newLayout.windowLayout != Adaptive::WindowLayout::OneColumn) {
|
||||||
|
dialogsWidthRatio().set(float64(newLayout.bodyWidth - requestedWidth) / newLayout.bodyWidth, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -36,6 +36,8 @@ class MainWindow;
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
public:
|
public:
|
||||||
|
static constexpr auto kDefaultDialogsWidthRatio = 5. / 14;
|
||||||
|
|
||||||
Controller(gsl::not_null<MainWindow*> window) : _window(window) {
|
Controller(gsl::not_null<MainWindow*> window) : _window(window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,24 @@ public:
|
||||||
}
|
}
|
||||||
bool isGifPausedAtLeastFor(GifPauseReason reason) const;
|
bool isGifPausedAtLeastFor(GifPauseReason reason) const;
|
||||||
|
|
||||||
|
struct ColumnLayout {
|
||||||
|
int bodyWidth;
|
||||||
|
int dialogsWidth;
|
||||||
|
Adaptive::WindowLayout windowLayout;
|
||||||
|
};
|
||||||
|
ColumnLayout computeColumnLayout();
|
||||||
|
bool provideChatWidth(int requestedWidth);
|
||||||
|
|
||||||
|
base::Variable<float64> &dialogsWidthRatio() {
|
||||||
|
return _dialogsWidthRatio;
|
||||||
|
}
|
||||||
|
base::Variable<bool> &dialogsListFocused() {
|
||||||
|
return _dialogsListFocused;
|
||||||
|
}
|
||||||
|
base::Variable<bool> &dialogsListDisplayForced() {
|
||||||
|
return _dialogsListDisplayForced;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gsl::not_null<MainWindow*> _window;
|
gsl::not_null<MainWindow*> _window;
|
||||||
|
|
||||||
|
@ -72,6 +92,10 @@ private:
|
||||||
GifPauseReasons _gifPauseReasons = { 0 };
|
GifPauseReasons _gifPauseReasons = { 0 };
|
||||||
base::Observable<void> _gifPauseLevelChanged;
|
base::Observable<void> _gifPauseLevelChanged;
|
||||||
|
|
||||||
|
base::Variable<float64> _dialogsWidthRatio = { kDefaultDialogsWidthRatio };
|
||||||
|
base::Variable<bool> _dialogsListFocused = { false };
|
||||||
|
base::Variable<bool> _dialogsListDisplayForced = { false };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
Loading…
Reference in New Issue