imageLoaded() notifications done through base::Subscriber.

Also FileDialog query completion notifications use base::Subscriber.
Strict lambda alignment check. Disable large lambdas in lambda_wrap.
This commit is contained in:
John Preston 2016-09-26 16:57:08 +03:00
parent 453661d611
commit 8546814a25
51 changed files with 210 additions and 217 deletions

View File

@ -47,7 +47,7 @@ private:
}; };
class AbstractBox : public LayerWidget { class AbstractBox : public LayerWidget, protected base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -1362,8 +1362,8 @@ RevokePublicLinkBox::RevokePublicLinkBox(base::lambda_unique<void()> &&revokeCal
updateMaxHeight(); updateMaxHeight();
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose())); connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
prepare(); prepare();
} }

View File

@ -29,13 +29,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
BackgroundInner::BackgroundInner() : BackgroundInner::BackgroundInner() :
_bgCount(0), _rows(0), _over(-1), _overDown(-1) { _bgCount(0), _rows(0), _over(-1), _overDown(-1) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
if (App::cServerBackgrounds().isEmpty()) { if (App::cServerBackgrounds().isEmpty()) {
resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding);
MTP::send(MTPaccount_GetWallPapers(), rpcDone(&BackgroundInner::gotWallpapers)); MTP::send(MTPaccount_GetWallPapers(), rpcDone(&BackgroundInner::gotWallpapers));
} else { } else {
updateWallpapers(); updateWallpapers();
} }
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
setMouseTracking(true); setMouseTracking(true);
} }

View File

@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "abstractbox.h" #include "abstractbox.h"
#include "core/lambda_wrap.h" #include "core/lambda_wrap.h"
class BackgroundInner : public QWidget, public RPCSender { class BackgroundInner : public TWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -546,7 +546,7 @@ ConfirmInviteBox::ConfirmInviteBox(const QString &title, const MTPChatPhoto &pho
if (!location.isNull()) { if (!location.isNull()) {
_photo = ImagePtr(location); _photo = ImagePtr(location);
if (!_photo->loaded()) { if (!_photo->loaded()) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
_photo->load(); _photo->load();
} }
} }

View File

@ -106,7 +106,7 @@ ContactsInner::ContactsInner(UserData *bot) : TWidget()
} }
void ContactsInner::init() { void ContactsInner::init() {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
connect(&_allAdmins, SIGNAL(changed()), this, SLOT(onAllAdminsChanged())); connect(&_allAdmins, SIGNAL(changed()), this, SLOT(onAllAdminsChanged()));
@ -1750,7 +1750,8 @@ MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right()) , _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right())
, _about(_aboutWidth) , _about(_aboutWidth)
, _aboutHeight(0) { , _aboutHeight(0) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&))); connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*))); connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*)));

View File

@ -36,7 +36,7 @@ using MembersAlreadyIn = OrderedSet<UserData*>;
QString cantInviteError(); QString cantInviteError();
class ConfirmBox; class ConfirmBox;
class ContactsInner : public TWidget, public RPCSender { class ContactsInner : public TWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
private: private:
@ -269,7 +269,7 @@ private:
}; };
class MembersInner : public TWidget, public RPCSender { class MembersInner : public TWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
private: private:

View File

@ -33,10 +33,11 @@ LocalStorageBox::LocalStorageBox() : AbstractBox()
connect(_clear, SIGNAL(clicked()), this, SLOT(onClear())); connect(_clear, SIGNAL(clicked()), this, SLOT(onClear()));
connect(_close, SIGNAL(clicked()), this, SLOT(onClose())); connect(_close, SIGNAL(clicked()), this, SLOT(onClose()));
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int))); connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int)));
connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int))); connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int)));
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
checkLocalStoredCounts(); checkLocalStoredCounts();
prepare(); prepare();
} }

View File

@ -243,8 +243,6 @@ namespace internal {
ShareInner::ShareInner(QWidget *parent) : ScrolledWidget(parent) ShareInner::ShareInner(QWidget *parent) : ScrolledWidget(parent)
, _chatsIndexed(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Add)) { , _chatsIndexed(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Add)) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
_rowsTop = st::shareRowsTop; _rowsTop = st::shareRowsTop;
_rowHeight = st::shareRowHeight; _rowHeight = st::shareRowHeight;
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
@ -264,7 +262,12 @@ ShareInner::ShareInner(QWidget *parent) : ScrolledWidget(parent)
using UpdateFlag = Notify::PeerUpdate::Flag; using UpdateFlag = Notify::PeerUpdate::Flag;
auto observeEvents = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged; auto observeEvents = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged;
Notify::registerPeerObserver(observeEvents, this, &ShareInner::notifyPeerUpdated);
Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
} }
void ShareInner::setVisibleTopBottom(int visibleTop, int visibleBottom) { void ShareInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {

View File

@ -108,7 +108,7 @@ private:
namespace internal { namespace internal {
class ShareInner : public ScrolledWidget, public RPCSender, public Notify::Observer { class ShareInner : public ScrolledWidget, public RPCSender, public Notify::Observer, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -41,7 +41,6 @@ constexpr int kArchivedLimitPerPage = 30;
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : ScrolledWidget() StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : ScrolledWidget()
, _input(set) { , _input(set) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
switch (set.type()) { switch (set.type()) {
case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break; case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break;
case mtpc_inputStickerSetShortName: _setShortName = qs(set.c_inputStickerSetShortName().vshort_name); break; case mtpc_inputStickerSetShortName: _setShortName = qs(set.c_inputStickerSetShortName().vshort_name); break;
@ -49,6 +48,8 @@ StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : ScrolledWidget
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet)); MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
App::main()->updateStickers(); App::main()->updateStickers();
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
setMouseTracking(true); setMouseTracking(true);
_previewTimer.setSingleShot(true); _previewTimer.setSingleShot(true);
@ -515,7 +516,7 @@ StickersInner::StickersInner(const Stickers::Order &archivedIds) : ScrolledWidge
} }
void StickersInner::setup() { void StickersInner::setup() {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(onImageLoaded())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
setMouseTracking(true); setMouseTracking(true);
} }

View File

@ -25,7 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
class ConfirmBox; class ConfirmBox;
class StickerSetInner : public ScrolledWidget, public RPCSender { class StickerSetInner : public ScrolledWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
@ -207,7 +207,7 @@ int32 stickerPacksCount(bool includeDisabledOfficial = false);
namespace internal { namespace internal {
class StickersInner : public ScrolledWidget, public RPCSender { class StickersInner : public ScrolledWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -1064,7 +1064,7 @@ extern QAtomicInt ComponentIndexLast;
template <typename Type> template <typename Type>
struct BaseComponent { struct BaseComponent {
BaseComponent() { BaseComponent() {
static_assert(alignof(Type) <= sizeof(SmallestSizeType), "Components should align to a pointer!"); static_assert(alignof(Type) <= alignof(SmallestSizeType), "Components should align to a pointer!");
} }
BaseComponent(const BaseComponent &other) = delete; BaseComponent(const BaseComponent &other) = delete;
BaseComponent &operator=(const BaseComponent &other) = delete; BaseComponent &operator=(const BaseComponent &other) = delete;

View File

@ -20,6 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#ifndef OS_MAC_OLD
#include <memory>
#endif // OS_MAC_OLD
namespace base { namespace base {
namespace internal { namespace internal {
@ -50,7 +54,7 @@ struct lambda_wrap_helper_base {
const call_type call; const call_type call;
const destruct_type destruct; const destruct_type destruct;
static constexpr size_t kFullStorageSize = 40U; static constexpr size_t kFullStorageSize = sizeof(void*) + 24U;
static constexpr size_t kStorageSize = kFullStorageSize - sizeof(void*); static constexpr size_t kStorageSize = kFullStorageSize - sizeof(void*);
template <typename Lambda> template <typename Lambda>
@ -90,43 +94,47 @@ const lambda_wrap_empty<Return, Args...> lambda_wrap_empty<Return, Args...>::ins
template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_move_impl; template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_move_impl;
template <typename Lambda, typename Return, typename ...Args> //
struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> { // Disable large lambda support.
using JustLambda = std_::decay_simple_t<Lambda>; // If you really need it, just store data in some std_::unique_ptr<struct>.
using LambdaPtr = std_::unique_ptr<JustLambda>; //
using Parent = lambda_wrap_helper_base<Return, Args...>; //template <typename Lambda, typename Return, typename ...Args>
static void construct_move_other_method(void *lambda, void *source) { //struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
auto source_lambda = static_cast<LambdaPtr*>(source); // using JustLambda = std_::decay_simple_t<Lambda>;
new (lambda) LambdaPtr(std_::move(*source_lambda)); // using LambdaPtr = std_::unique_ptr<JustLambda>;
} // using Parent = lambda_wrap_helper_base<Return, Args...>;
static void construct_move_lambda_method(void *lambda, void *source) { // static void construct_move_other_method(void *lambda, void *source) {
auto source_lambda = static_cast<JustLambda*>(source); // auto source_lambda = static_cast<LambdaPtr*>(source);
new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda))); // new (lambda) LambdaPtr(std_::move(*source_lambda));
} // }
static Return call_method(const void *lambda, Args... args) { // static void construct_move_lambda_method(void *lambda, void *source) {
return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...); // auto source_lambda = static_cast<JustLambda*>(source);
} // new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
static void destruct_method(const void *lambda) { // }
static_cast<const LambdaPtr*>(lambda)->~LambdaPtr(); // static Return call_method(const void *lambda, Args... args) {
} // return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...);
lambda_wrap_helper_move_impl() : Parent( // }
&Parent::bad_construct_copy, // static void destruct_method(const void *lambda) {
&lambda_wrap_helper_move_impl::construct_move_other_method, // static_cast<const LambdaPtr*>(lambda)->~LambdaPtr();
&lambda_wrap_helper_move_impl::call_method, // }
&lambda_wrap_helper_move_impl::destruct_method) { // lambda_wrap_helper_move_impl() : Parent(
} // &Parent::bad_construct_copy,
// &lambda_wrap_helper_move_impl::construct_move_other_method,
protected: // &lambda_wrap_helper_move_impl::call_method,
lambda_wrap_helper_move_impl( // &lambda_wrap_helper_move_impl::destruct_method) {
typename Parent::construct_copy_other_type construct_copy_other // }
) : Parent( //
construct_copy_other, //protected:
&lambda_wrap_helper_move_impl::construct_move_other_method, // lambda_wrap_helper_move_impl(
&lambda_wrap_helper_move_impl::call_method, // typename Parent::construct_copy_other_type construct_copy_other
&lambda_wrap_helper_move_impl::destruct_method) { // ) : Parent(
} // construct_copy_other,
// &lambda_wrap_helper_move_impl::construct_move_other_method,
}; // &lambda_wrap_helper_move_impl::call_method,
// &lambda_wrap_helper_move_impl::destruct_method) {
// }
//
//};
template <typename Lambda, typename Return, typename ...Args> template <typename Lambda, typename Return, typename ...Args>
struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> { struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
@ -137,6 +145,12 @@ struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> :
new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda)); new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda));
} }
static void construct_move_lambda_method(void *lambda, void *source) { static void construct_move_lambda_method(void *lambda, void *source) {
static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
#ifndef OS_MAC_OLD
auto space = sizeof(JustLambda);
auto aligned = std::align(alignof(JustLambda), space, lambda, space);
t_assert(aligned == lambda);
#endif // OS_MAC_OLD
auto source_lambda = static_cast<JustLambda*>(source); auto source_lambda = static_cast<JustLambda*>(source);
new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda)); new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda));
} }
@ -177,23 +191,27 @@ const lambda_wrap_helper_move<Lambda, Return, Args...> lambda_wrap_helper_move<L
template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_copy_impl; template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_copy_impl;
template <typename Lambda, typename Return, typename ...Args> //
struct lambda_wrap_helper_copy_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> { // Disable large lambda support.
using JustLambda = std_::decay_simple_t<Lambda>; // If you really need it, just store data in some QSharedPointer<struct>.
using LambdaPtr = std_::unique_ptr<JustLambda>; //
using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>; //template <typename Lambda, typename Return, typename ...Args>
static void construct_copy_other_method(void *lambda, const void *source) { //struct lambda_wrap_helper_copy_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> {
auto source_lambda = static_cast<const LambdaPtr*>(source); // using JustLambda = std_::decay_simple_t<Lambda>;
new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get())); // using LambdaPtr = std_::unique_ptr<JustLambda>;
} // using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>;
static void construct_copy_lambda_method(void *lambda, const void *source) { // static void construct_copy_other_method(void *lambda, const void *source) {
auto source_lambda = static_cast<const JustLambda*>(source); // auto source_lambda = static_cast<const LambdaPtr*>(source);
new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<const JustLambda &>(*source_lambda))); // new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get()));
} // }
lambda_wrap_helper_copy_impl() : Parent(&lambda_wrap_helper_copy_impl::construct_copy_other_method) { // static void construct_copy_lambda_method(void *lambda, const void *source) {
} // auto source_lambda = static_cast<const JustLambda*>(source);
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<const JustLambda &>(*source_lambda)));
}; // }
// lambda_wrap_helper_copy_impl() : Parent(&lambda_wrap_helper_copy_impl::construct_copy_other_method) {
// }
//
//};
template <typename Lambda, typename Return, typename ...Args> template <typename Lambda, typename Return, typename ...Args>
struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> { struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> {
@ -204,6 +222,12 @@ struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> :
new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda)); new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda));
} }
static void construct_copy_lambda_method(void *lambda, const void *source) { static void construct_copy_lambda_method(void *lambda, const void *source) {
static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
#ifndef OS_MAC_OLD
auto space = sizeof(JustLambda);
auto aligned = std::align(alignof(JustLambda), space, lambda, space);
t_assert(aligned == lambda);
#endif // OS_MAC_OLD
auto source_lambda = static_cast<const JustLambda*>(source); auto source_lambda = static_cast<const JustLambda*>(source);
new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda)); new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda));
} }
@ -356,7 +380,7 @@ public:
auto temp = other; auto temp = other;
this->helper_->destruct(this->storage_); this->helper_->destruct(this->storage_);
this->helper_ = &internal::lambda_wrap_helper_copy<Lambda, Return, Args...>::instance; this->helper_ = &internal::lambda_wrap_helper_copy<Lambda, Return, Args...>::instance;
internal::lambda_wrap_helper_copy<Lambda, Return, Args...>::construct_move_lambda_method(this->storage_, &other); internal::lambda_wrap_helper_copy<Lambda, Return, Args...>::construct_copy_lambda_method(this->storage_, &other);
return *this; return *this;
} }

View File

@ -46,13 +46,15 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
if (Global::DialogsModeEnabled()) { if (Global::DialogsModeEnabled()) {
importantDialogs = std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date); importantDialogs = std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date);
} }
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&))); connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*))); connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
connect(main, SIGNAL(dialogRowReplaced(Dialogs::Row*,Dialogs::Row*)), this, SLOT(onDialogRowReplaced(Dialogs::Row*,Dialogs::Row*))); connect(main, SIGNAL(dialogRowReplaced(Dialogs::Row*,Dialogs::Row*)), this, SLOT(onDialogRowReplaced(Dialogs::Row*,Dialogs::Row*)));
connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer())); connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer()));
_cancelSearchInPeer.hide(); _cancelSearchInPeer.hide();
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
refresh(); refresh();
} }

View File

@ -42,7 +42,7 @@ enum DialogsSearchRequestType {
DialogsSearchMigratedFromOffset, DialogsSearchMigratedFromOffset,
}; };
class DialogsInner : public SplittedWidget, public RPCSender { class DialogsInner : public SplittedWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -44,8 +44,6 @@ FieldAutocomplete::FieldAutocomplete(QWidget *parent) : TWidget(parent)
connect(_inner, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod)), this, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod))); connect(_inner, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod)), this, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod)));
connect(_inner, SIGNAL(mustScrollTo(int, int)), _scroll, SLOT(scrollToY(int, int))); connect(_inner, SIGNAL(mustScrollTo(int, int)), _scroll, SLOT(scrollToY(int, int)));
connect(App::wnd(), SIGNAL(imageLoaded()), _inner, SLOT(update()));
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
_scroll->setFocusPolicy(Qt::NoFocus); _scroll->setFocusPolicy(Qt::NoFocus);
_scroll->viewport()->setFocusPolicy(Qt::NoFocus); _scroll->viewport()->setFocusPolicy(Qt::NoFocus);
@ -539,6 +537,7 @@ FieldAutocompleteInner::FieldAutocompleteInner(FieldAutocomplete *parent, Mentio
, _previewShown(false) { , _previewShown(false) {
_previewTimer.setSingleShot(true); _previewTimer.setSingleShot(true);
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview())); connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
} }
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) { void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
@ -933,7 +932,4 @@ void FieldAutocompleteInner::onPreview() {
} }
} }
FieldAutocompleteInner::~FieldAutocompleteInner() {
}
} // namespace internal } // namespace internal

View File

@ -138,7 +138,7 @@ private:
namespace internal { namespace internal {
class FieldAutocompleteInner final : public TWidget { class FieldAutocompleteInner final : public TWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
@ -150,8 +150,6 @@ public:
void setRecentInlineBotsInRows(int32 bots); void setRecentInlineBotsInRows(int32 bots);
~FieldAutocompleteInner();
signals: signals:
void mentionChosen(UserData *user, FieldAutocomplete::ChooseMethod method) const; void mentionChosen(UserData *user, FieldAutocomplete::ChooseMethod method) const;
void hashtagChosen(QString hashtag, FieldAutocomplete::ChooseMethod method) const; void hashtagChosen(QString hashtag, FieldAutocomplete::ChooseMethod method) const;

View File

@ -3040,7 +3040,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
setAcceptDrops(true); setAcceptDrops(true);
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(&_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked())); connect(&_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked()));
connect(&_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide())); connect(&_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide()));

View File

@ -437,7 +437,7 @@ MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent)
, _a_shown(animation(this, &MediaPreviewWidget::step_shown)) , _a_shown(animation(this, &MediaPreviewWidget::step_shown))
, _emojiSize(EmojiSizes[EIndex + 1] / cIntRetinaFactor()) { , _emojiSize(EmojiSizes[EIndex + 1] / cIntRetinaFactor()) {
setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_TransparentForMouseEvents);
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
} }
void MediaPreviewWidget::paintEvent(QPaintEvent *e) { void MediaPreviewWidget::paintEvent(QPaintEvent *e) {

View File

@ -129,7 +129,7 @@ private:
}; };
class MediaPreviewWidget : public TWidget { class MediaPreviewWidget : public TWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -406,8 +406,7 @@ MainWindow::MainWindow() {
connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock())); connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock()));
connect(this, SIGNAL(imageLoaded()), this, SLOT(notifyUpdateAllPhotos())); subscribe(FileDownload::ImageLoaded(), [this] { notifyUpdateAllPhotos(); });
subscribe(Global::RefSelfChanged(), [this]() { updateGlobalMenu(); }); subscribe(Global::RefSelfChanged(), [this]() { updateGlobalMenu(); });
setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_NoSystemBackground);

View File

@ -292,8 +292,6 @@ signals:
void tempDirClearFailed(int task); void tempDirClearFailed(int task);
void newAuthorization(); void newAuthorization();
void imageLoaded();
private slots: private slots:
void onStateChanged(Qt::WindowState state); void onStateChanged(Qt::WindowState state);
void onSettingsDestroyed(QObject *was); void onSettingsDestroyed(QObject *was);

View File

@ -206,7 +206,7 @@ namespace {
} }
req = i.value(); req = i.value();
} }
if (internal::Session *session = internal::getSession(newdcWithShift)) { if (auto session = internal::getSession(newdcWithShift)) {
internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift); internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
session->sendPrepared(req); session->sendPrepared(req);
} }

View File

@ -207,9 +207,8 @@ void FileLoader::localLoaded(const StorageImageSaved &result, const QByteArray &
_fileIsOpen = false; _fileIsOpen = false;
psPostprocessFile(QFileInfo(_file).absoluteFilePath()); psPostprocessFile(QFileInfo(_file).absoluteFilePath());
} }
emit App::wnd()->imageLoaded();
emit progress(this); emit progress(this);
FileDownload::internal::notifyImageLoaded(); FileDownload::ImageLoaded().notify();
loadNext(); loadNext();
} }
@ -516,8 +515,6 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe
} }
removeFromQueue(); removeFromQueue();
emit App::wnd()->imageLoaded();
if (!_queue->queries) { if (!_queue->queries) {
App::app()->killDownloadSessionsStart(_dc); App::app()->killDownloadSessionsStart(_dc);
} }
@ -544,7 +541,7 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe
} }
emit progress(this); emit progress(this);
if (_complete) { if (_complete) {
FileDownload::internal::notifyImageLoaded(); FileDownload::ImageLoaded().notify();
} }
loadNext(); loadNext();
} }
@ -669,13 +666,11 @@ void webFileLoader::onFinished(const QByteArray &data) {
} }
removeFromQueue(); removeFromQueue();
emit App::wnd()->imageLoaded();
if (_localStatus == LocalNotFound || _localStatus == LocalFailed) { if (_localStatus == LocalNotFound || _localStatus == LocalFailed) {
Local::writeWebFile(_url, _data); Local::writeWebFile(_url, _data);
} }
emit progress(this); emit progress(this);
FileDownload::internal::notifyImageLoaded(); FileDownload::ImageLoaded().notify();
loadNext(); loadNext();
} }
@ -1093,21 +1088,12 @@ namespace MTP {
namespace FileDownload { namespace FileDownload {
namespace { namespace {
using internal::ImageLoadedHandler; base::Observable<void> ImageLoadedObservable;
Notify::SimpleObservedEventRegistrator<ImageLoadedHandler> creator(nullptr, nullptr);
} // namespace } // namespace
namespace internal { base::Observable<void> &ImageLoaded() {
return ImageLoadedObservable;
Notify::ConnectionId plainRegisterImageLoadedObserver(ImageLoadedHandler &&handler) {
return creator.registerObserver(std_::forward<ImageLoadedHandler>(handler));
} }
void notifyImageLoaded() { } // namespace FileDownload
creator.notify();
}
} // namespace internal
}

View File

@ -397,21 +397,6 @@ void stopWebLoadManager();
namespace FileDownload { namespace FileDownload {
namespace internal { base::Observable<void> &ImageLoaded();
using ImageLoadedHandler = base::lambda_unique<void()>;
Notify::ConnectionId plainRegisterImageLoadedObserver(ImageLoadedHandler &&handler);
void notifyImageLoaded();
} // namespace internal
template <typename ObserverType>
void registerImageLoadedObserver(ObserverType *observer, void (ObserverType::*handler)()) {
auto connection = internal::plainRegisterImageLoadedObserver([observer, handler]() {
(observer->*handler)();
});
Notify::observerRegistered(observer, connection);
}
} // namespace FileDownload } // namespace FileDownload

View File

@ -96,11 +96,9 @@ ConnectionId plainRegisterPeerObserver(PeerUpdate::Flags events, PeerUpdateHandl
} // namespace internal } // namespace internal
template <typename ObserverType> template <typename ObserverType, typename Lambda>
void registerPeerObserver(PeerUpdate::Flags events, ObserverType *observer, void (ObserverType::*handler)(const PeerUpdate &)) { void registerPeerObserver(PeerUpdate::Flags events, ObserverType *observer, Lambda &&other) {
auto connection = internal::plainRegisterPeerObserver(events, [observer, handler](const PeerUpdate &update) { auto connection = internal::plainRegisterPeerObserver(events, std_::move(other));
(observer->*handler)(update);
});
observerRegistered(observer, connection); observerRegistered(observer, connection);
} }

View File

@ -89,7 +89,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
, _touchAccelerationTime(0) , _touchAccelerationTime(0)
, _touchTime(0) , _touchTime(0)
, _menu(0) { , _menu(0) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
resize(_width, st::wndMinHeight); resize(_width, st::wndMinHeight);

View File

@ -33,7 +33,7 @@ class Date;
} // namespace Overview } // namespace Overview
class OverviewWidget; class OverviewWidget;
class OverviewInner : public QWidget, public AbstractTooltipShower, public RPCSender { class OverviewInner : public QWidget, public AbstractTooltipShower, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -39,7 +39,9 @@ ActionsWidget::ActionsWidget(QWidget *parent, PeerData *peer) : BlockWidget(pare
| UpdateFlag::UserIsBlocked | UpdateFlag::UserIsBlocked
| UpdateFlag::BotCommandsChanged | UpdateFlag::BotCommandsChanged
| UpdateFlag::MembersChanged; | UpdateFlag::MembersChanged;
Notify::registerPeerObserver(observeEvents, this, &ActionsWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
validateBlockStatus(); validateBlockStatus();
refreshButtons(); refreshButtons();

View File

@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Profile { namespace Profile {
class BlockWidget : public ScrolledWidget, public Notify::Observer { class BlockWidget : public ScrolledWidget, public Notify::Observer, protected base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -68,8 +68,12 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
auto observeEvents = ButtonsUpdateFlags auto observeEvents = ButtonsUpdateFlags
| UpdateFlag::NameChanged | UpdateFlag::NameChanged
| UpdateFlag::UserOnlineChanged; | UpdateFlag::UserOnlineChanged;
Notify::registerPeerObserver(observeEvents, this, &CoverWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
FileDialog::registerObserver(this, &CoverWidget::notifyFileQueryUpdated); notifyPeerUpdated(update);
});
subscribe(FileDialog::QueryDone(), [this](const FileDialog::QueryUpdate &update) {
notifyFileQueryUpdated(update);
});
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId)));
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId)));

View File

@ -40,7 +40,7 @@ class BackButton;
class UserpicButton; class UserpicButton;
class CoverDropArea; class CoverDropArea;
class CoverWidget final : public TWidget, public Notify::Observer { class CoverWidget final : public TWidget, public Notify::Observer, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -83,7 +83,9 @@ FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent)
auto observeEvents = ButtonsUpdateFlags auto observeEvents = ButtonsUpdateFlags
| UpdateFlag::MigrationChanged; | UpdateFlag::MigrationChanged;
Notify::registerPeerObserver(observeEvents, this, &FixedBar::notifyPeerUpdate); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdate(update);
});
refreshRightActions(); refreshRightActions();
} }

View File

@ -36,7 +36,9 @@ InfoWidget::InfoWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, pe
| UpdateFlag::UsernameChanged | UpdateFlag::UsernameChanged
| UpdateFlag::UserPhoneChanged | UpdateFlag::UserPhoneChanged
| UpdateFlag::UserCanShareContact; | UpdateFlag::UserCanShareContact;
Notify::registerPeerObserver(observeEvents, this, &InfoWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
refreshLabels(); refreshLabels();
} }

View File

@ -33,7 +33,9 @@ using UpdateFlag = Notify::PeerUpdate::Flag;
InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section)) { InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section)) {
auto observeEvents = UpdateFlag::InviteLinkChanged | UpdateFlag::UsernameChanged; auto observeEvents = UpdateFlag::InviteLinkChanged | UpdateFlag::UsernameChanged;
Notify::registerPeerObserver(observeEvents, this, &InviteLinkWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
refreshLink(); refreshLink();
refreshVisibility(); refreshVisibility();

View File

@ -49,16 +49,14 @@ MembersWidget::MembersWidget(QWidget *parent, PeerData *peer, TitleVisibility ti
auto observeEvents = UpdateFlag::AdminsChanged auto observeEvents = UpdateFlag::AdminsChanged
| UpdateFlag::MembersChanged | UpdateFlag::MembersChanged
| UpdateFlag::UserOnlineChanged; | UpdateFlag::UserOnlineChanged;
Notify::registerPeerObserver(observeEvents, this, &MembersWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
FileDownload::registerImageLoadedObserver(this, &MembersWidget::repaintCallback); notifyPeerUpdated(update);
});
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
refreshMembers(); refreshMembers();
} }
void MembersWidget::repaintCallback() {
update();
}
void MembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { void MembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.peer != peer()) { if (update.peer != peer()) {
if (update.flags & UpdateFlag::UserOnlineChanged) { if (update.flags & UpdateFlag::UserOnlineChanged) {
@ -83,7 +81,7 @@ void MembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
} }
} }
} }
repaintCallback(); this->update();
} }
void MembersWidget::refreshUserOnline(UserData *user) { void MembersWidget::refreshUserOnline(UserData *user) {
@ -606,7 +604,9 @@ ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : Bl
| UpdateFlag::ChannelCanViewMembers | UpdateFlag::ChannelCanViewMembers
| UpdateFlag::AdminsChanged | UpdateFlag::AdminsChanged
| UpdateFlag::MembersChanged; | UpdateFlag::MembersChanged;
Notify::registerPeerObserver(observeEvents, this, &ChannelMembersWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
refreshButtons(); refreshButtons();
} }

View File

@ -78,7 +78,6 @@ private slots:
private: private:
// Observed notifications. // Observed notifications.
void notifyPeerUpdated(const Notify::PeerUpdate &update); void notifyPeerUpdated(const Notify::PeerUpdate &update);
void repaintCallback();
void preloadUserPhotos(); void preloadUserPhotos();

View File

@ -51,7 +51,9 @@ SettingsWidget::SettingsWidget(QWidget *parent, PeerData *peer) : BlockWidget(pa
observeEvents |= UpdateFlag::UsernameChanged | UpdateFlag::InviteLinkChanged; observeEvents |= UpdateFlag::UsernameChanged | UpdateFlag::InviteLinkChanged;
} }
} }
Notify::registerPeerObserver(observeEvents, this, &SettingsWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
refreshButtons(); refreshButtons();
_enableNotifications->finishAnimations(); _enableNotifications->finishAnimations();

View File

@ -51,7 +51,9 @@ QString getButtonText(MediaOverviewType type, int count) {
SharedMediaWidget::SharedMediaWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_shared_media)) SharedMediaWidget::SharedMediaWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_shared_media))
, _history(App::history(peer)) , _history(App::history(peer))
, _migrated(peer->migrateFrom() ? App::history(peer->migrateFrom()) : nullptr) { , _migrated(peer->migrateFrom() ? App::history(peer->migrateFrom()) : nullptr) {
Notify::registerPeerObserver(Notify::PeerUpdate::Flag::SharedMediaChanged, this, &SharedMediaWidget::notifyPeerUpdated); Notify::registerPeerObserver(Notify::PeerUpdate::Flag::SharedMediaChanged, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
App::main()->preloadOverviews(peer); App::main()->preloadOverviews(peer);
if (_migrated) { if (_migrated) {

View File

@ -36,8 +36,15 @@ UserpicButton::UserpicButton(QWidget *parent, PeerData *peer) : Button(parent),
_userpic = prepareUserpicPixmap(); _userpic = prepareUserpicPixmap();
} }
Notify::registerPeerObserver(Notify::PeerUpdate::Flag::PhotoChanged, this, &UserpicButton::notifyPeerUpdated); Notify::registerPeerObserver(Notify::PeerUpdate::Flag::PhotoChanged, this, [this](const Notify::PeerUpdate &update) {
FileDownload::registerImageLoadedObserver(this, &UserpicButton::notifyImageLoaded); notifyPeerUpdated(update);
});
subscribe(FileDownload::ImageLoaded(), [this] {
if (_waiting && _peer->userpicLoaded()) {
_waiting = false;
startNewPhotoShowing();
}
});
} }
void UserpicButton::showFinished() { void UserpicButton::showFinished() {
@ -68,13 +75,6 @@ void UserpicButton::notifyPeerUpdated(const Notify::PeerUpdate &update) {
this->update(); this->update();
} }
void UserpicButton::notifyImageLoaded() {
if (_waiting && _peer->userpicLoaded()) {
_waiting = false;
startNewPhotoShowing();
}
}
void UserpicButton::processPeerPhoto() { void UserpicButton::processPeerPhoto() {
bool hasPhoto = (_peer->photoId && _peer->photoId != UnknownPeerPhotoId); bool hasPhoto = (_peer->photoId && _peer->photoId != UnknownPeerPhotoId);
setCursor(hasPhoto ? style::cur_pointer : style::cur_default); setCursor(hasPhoto ? style::cur_pointer : style::cur_default);

View File

@ -28,7 +28,7 @@ struct PeerUpdate;
namespace Profile { namespace Profile {
class UserpicButton final : public Button, public Notify::Observer { class UserpicButton final : public Button, public Notify::Observer, private base::Subscriber {
public: public:
UserpicButton(QWidget *parent, PeerData *peer); UserpicButton(QWidget *parent, PeerData *peer);
@ -41,7 +41,6 @@ protected:
private: private:
void notifyPeerUpdated(const Notify::PeerUpdate &update); void notifyPeerUpdated(const Notify::PeerUpdate &update);
void notifyImageLoaded();
void processPeerPhoto(); void processPeerPhoto();
void processNewPeerPhoto(); void processNewPeerPhoto();

View File

@ -163,9 +163,11 @@ void BackgroundRow::updateImage() {
} }
BackgroundWidget::BackgroundWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_background)) { BackgroundWidget::BackgroundWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_background)) {
FileDialog::registerObserver(this, &BackgroundWidget::notifyFileQueryUpdated);
createControls(); createControls();
subscribe(FileDialog::QueryDone(), [this](const FileDialog::QueryUpdate &update) {
notifyFileQueryUpdated(update);
});
subscribe(Window::chatBackground(), [this](const Window::ChatBackgroundUpdate &update) { subscribe(Window::chatBackground(), [this](const Window::ChatBackgroundUpdate &update) {
using Update = Window::ChatBackgroundUpdate; using Update = Window::ChatBackgroundUpdate;
if (update.type == Update::Type::New) { if (update.type == Update::Type::New) {

View File

@ -57,8 +57,13 @@ CoverWidget::CoverWidget(QWidget *parent, UserData *self) : BlockWidget(parent,
connect(_editNameInline, SIGNAL(clicked()), this, SLOT(onEditName())); connect(_editNameInline, SIGNAL(clicked()), this, SLOT(onEditName()));
auto observeEvents = Notify::PeerUpdate::Flag::NameChanged; auto observeEvents = Notify::PeerUpdate::Flag::NameChanged;
Notify::registerPeerObserver(observeEvents, this, &CoverWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
FileDialog::registerObserver(this, &CoverWidget::notifyFileQueryUpdated); notifyPeerUpdated(update);
});
subscribe(FileDialog::QueryDone(), [this](const FileDialog::QueryUpdate &update) {
notifyFileQueryUpdated(update);
});
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId)));
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId)));

View File

@ -171,7 +171,9 @@ GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(pare
, _changeLanguage(this, lang(lng_settings_change_lang), st::defaultBoxLinkButton) { , _changeLanguage(this, lang(lng_settings_change_lang), st::defaultBoxLinkButton) {
connect(_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage())); connect(_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage()));
subscribe(Global::RefChooseCustomLang(), [this]() { chooseCustomLang(); }); subscribe(Global::RefChooseCustomLang(), [this]() { chooseCustomLang(); });
FileDialog::registerObserver(this, &GeneralWidget::notifyFileQueryUpdated); subscribe(FileDialog::QueryDone(), [this](const FileDialog::QueryUpdate &update) {
notifyFileQueryUpdated(update);
});
refreshControls(); refreshControls();
} }

View File

@ -34,7 +34,9 @@ using UpdateFlag = Notify::PeerUpdate::Flag;
InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_info)) { InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_info)) {
auto observeEvents = UpdateFlag::UsernameChanged | UpdateFlag::UserPhoneChanged; auto observeEvents = UpdateFlag::UsernameChanged | UpdateFlag::UserPhoneChanged;
Notify::registerPeerObserver(observeEvents, this, &InfoWidget::notifyPeerUpdated); Notify::registerPeerObserver(observeEvents, this, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
});
createControls(); createControls();
} }

View File

@ -801,7 +801,6 @@ StickerPanInner::StickerPanInner() : ScrolledWidget()
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(onImageLoaded()));
connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings())); connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings()));
_previewTimer.setSingleShot(true); _previewTimer.setSingleShot(true);
@ -809,6 +808,11 @@ StickerPanInner::StickerPanInner() : ScrolledWidget()
_updateInlineItems.setSingleShot(true); _updateInlineItems.setSingleShot(true);
connect(&_updateInlineItems, SIGNAL(timeout()), this, SLOT(onUpdateInlineItems())); connect(&_updateInlineItems, SIGNAL(timeout()), this, SLOT(onUpdateInlineItems()));
subscribe(FileDownload::ImageLoaded(), [this] {
update();
readVisibleSets();
});
} }
void StickerPanInner::setMaxHeight(int32 h) { void StickerPanInner::setMaxHeight(int32 h) {
@ -855,11 +859,6 @@ void StickerPanInner::readVisibleSets() {
} }
} }
void StickerPanInner::onImageLoaded() {
update();
readVisibleSets();
}
int StickerPanInner::featuredRowHeight() const { int StickerPanInner::featuredRowHeight() const {
return st::featuredStickersHeader + st::stickerPanSize.height() + st::featuredStickersSkip; return st::featuredStickersHeader + st::stickerPanSize.height() + st::featuredStickersSkip;
} }

View File

@ -207,7 +207,7 @@ struct StickerIcon {
int pixh = 0; int pixh = 0;
}; };
class StickerPanInner : public ScrolledWidget { class StickerPanInner : public ScrolledWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
@ -274,7 +274,6 @@ private slots:
void onPreview(); void onPreview();
void onUpdateInlineItems(); void onUpdateInlineItems();
void onSwitchPm(); void onSwitchPm();
void onImageLoaded();
signals: signals:
void selected(DocumentData *sticker); void selected(DocumentData *sticker);

View File

@ -27,12 +27,11 @@ static const ChannelId NoChannel = 0;
typedef int32 MsgId; typedef int32 MsgId;
struct FullMsgId { struct FullMsgId {
FullMsgId() : channel(NoChannel), msg(0) { FullMsgId() = default;
}
FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) { FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) {
} }
ChannelId channel; ChannelId channel = NoChannel;
MsgId msg; MsgId msg = 0;
}; };
typedef uint64 PeerId; typedef uint64 PeerId;

View File

@ -255,7 +255,7 @@ QString filedialogAllFilesFilter() {
namespace FileDialog { namespace FileDialog {
namespace { namespace {
using internal::QueryUpdateHandler; base::Observable<QueryUpdate> QueryDoneObservable;
struct Query { struct Query {
enum class Type { enum class Type {
@ -285,16 +285,10 @@ void StartCallback() {
Queries.makeIfNull(); Queries.makeIfNull();
} }
void FinishCallback() {
Queries.clear();
}
Notify::SimpleObservedEventRegistrator<QueryUpdateHandler> creator(StartCallback, FinishCallback);
} // namespace } // namespace
QueryId queryReadFile(const QString &caption, const QString &filter) { QueryId queryReadFile(const QString &caption, const QString &filter) {
t_assert(creator.started()); Queries.makeIfNull();
Queries->push_back(Query(Query::Type::ReadFile, caption, filter)); Queries->push_back(Query(Query::Type::ReadFile, caption, filter));
Global::RefHandleFileDialogQueue().call(); Global::RefHandleFileDialogQueue().call();
@ -302,7 +296,7 @@ QueryId queryReadFile(const QString &caption, const QString &filter) {
} }
QueryId queryReadFiles(const QString &caption, const QString &filter) { QueryId queryReadFiles(const QString &caption, const QString &filter) {
t_assert(creator.started()); Queries.makeIfNull();
Queries->push_back(Query(Query::Type::ReadFiles, caption, filter)); Queries->push_back(Query(Query::Type::ReadFiles, caption, filter));
Global::RefHandleFileDialogQueue().call(); Global::RefHandleFileDialogQueue().call();
@ -310,7 +304,7 @@ QueryId queryReadFiles(const QString &caption, const QString &filter) {
} }
QueryId queryWriteFile(const QString &caption, const QString &filter, const QString &filePath) { QueryId queryWriteFile(const QString &caption, const QString &filter, const QString &filePath) {
t_assert(creator.started()); Queries.makeIfNull();
Queries->push_back(Query(Query::Type::WriteFile, caption, filter, filePath)); Queries->push_back(Query(Query::Type::WriteFile, caption, filter, filePath));
Global::RefHandleFileDialogQueue().call(); Global::RefHandleFileDialogQueue().call();
@ -318,7 +312,7 @@ QueryId queryWriteFile(const QString &caption, const QString &filter, const QStr
} }
QueryId queryReadFolder(const QString &caption) { QueryId queryReadFolder(const QString &caption) {
t_assert(creator.started()); Queries.makeIfNull();
Queries->push_back(Query(Query::Type::ReadFolder, caption)); Queries->push_back(Query(Query::Type::ReadFolder, caption));
Global::RefHandleFileDialogQueue().call(); Global::RefHandleFileDialogQueue().call();
@ -326,7 +320,7 @@ QueryId queryReadFolder(const QString &caption) {
} }
bool processQuery() { bool processQuery() {
if (!creator.started() || !Global::started() || Queries->isEmpty()) return false; if (!Queries || !Global::started() || Queries->isEmpty()) return false;
auto query = Queries->front(); auto query = Queries->front();
Queries->pop_front(); Queries->pop_front();
@ -374,17 +368,14 @@ bool processQuery() {
} }
// No one knows what happened during filedialogGet*() call in the event loop. // No one knows what happened during filedialogGet*() call in the event loop.
if (!creator.started() || !Global::started()) return false; if (!Queries || !Global::started()) return false;
creator.notify(update); QueryDone().notify(std_::move(update));
return true; return true;
} }
namespace internal { base::Observable<QueryUpdate> &QueryDone() {
return QueryDoneObservable;
Notify::ConnectionId plainRegisterObserver(QueryUpdateHandler &&handler) {
return creator.registerObserver(std_::forward<QueryUpdateHandler>(handler));
} }
} // namespace internal
} // namespace FileDialog } // namespace FileDialog

View File

@ -63,19 +63,6 @@ QueryId queryReadFolder(const QString &caption);
// NB! This function enters an event loop. // NB! This function enters an event loop.
bool processQuery(); bool processQuery();
namespace internal { base::Observable<QueryUpdate> &QueryDone();
using QueryUpdateHandler = base::lambda_unique<void(const QueryUpdate&)>;
Notify::ConnectionId plainRegisterObserver(QueryUpdateHandler &&handler);
} // namespace internal
template <typename ObserverType>
void registerObserver(ObserverType *observer, void (ObserverType::*handler)(const QueryUpdate &)) {
auto connection = internal::plainRegisterObserver([observer, handler](const QueryUpdate &update) {
(observer->*handler)(update);
});
Notify::observerRegistered(observer, connection);
}
} // namespace FileDialog } // namespace FileDialog