Destroy members dropdown when the peer changes.

Also use object_ptr for passing widget in InnerDropdown.
This commit is contained in:
John Preston 2017-05-26 17:36:59 +03:00
parent 6148b78745
commit 9e3f13ba2e
5 changed files with 31 additions and 25 deletions

View File

@ -84,6 +84,7 @@ constexpr auto kTabbedSelectorToggleTooltipTimeoutMs = 3000;
constexpr auto kTabbedSelectorToggleTooltipCount = 3; constexpr auto kTabbedSelectorToggleTooltipCount = 3;
constexpr auto kScrollToVoiceAfterScrolledMs = 1000; constexpr auto kScrollToVoiceAfterScrolledMs = 1000;
constexpr auto kSkipRepaintWhileScrollMs = 100; constexpr auto kSkipRepaintWhileScrollMs = 100;
constexpr auto kShowMembersDropdownTimeoutMs = 300;
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() { ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
return [](ChannelData *channel, MsgId msgId) { return [](ChannelData *channel, MsgId msgId) {
@ -1834,6 +1835,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
destroyUnreadBar(); destroyUnreadBar();
destroyPinnedBar(); destroyPinnedBar();
_membersDropdown.destroy();
_scrollToAnimation.finish(); _scrollToAnimation.finish();
_history = _migrated = nullptr; _history = _migrated = nullptr;
_peer = nullptr; _peer = nullptr;
@ -3868,7 +3870,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) {
if (_membersDropdown) { if (_membersDropdown) {
_membersDropdown->otherEnter(); _membersDropdown->otherEnter();
} else if (!_membersDropdownShowTimer.isActive()) { } else if (!_membersDropdownShowTimer.isActive()) {
_membersDropdownShowTimer.start(300); _membersDropdownShowTimer.start(kShowMembersDropdownTimeoutMs);
} }
} else if (_membersDropdown) { } else if (_membersDropdown) {
_membersDropdown->otherLeave(); _membersDropdown->otherLeave();
@ -3878,7 +3880,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) {
void HistoryWidget::onMembersDropdownShow() { void HistoryWidget::onMembersDropdownShow() {
if (!_membersDropdown) { if (!_membersDropdown) {
_membersDropdown.create(this, st::membersInnerDropdown); _membersDropdown.create(this, st::membersInnerDropdown);
_membersDropdown->setOwnedWidget(new Profile::GroupMembersWidget(_membersDropdown, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem)); _membersDropdown->setOwnedWidget(object_ptr<Profile::GroupMembersWidget>(this, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem));
_membersDropdown->resizeToWidth(st::membersInnerWidth); _membersDropdown->resizeToWidth(st::membersInnerWidth);
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax()); _membersDropdown->setMaxHeight(countMembersDropdownHeightMax());

View File

@ -23,15 +23,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace Ui { namespace Ui {
DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap) DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap)
, _st(st) , _st(st) {
, _menu(this, _st.menu) { _menu = setOwnedWidget(object_ptr<Ui::Menu>(this, _st.menu));
init(); init();
} }
// Not ready with submenus yet. // Not ready with submenus yet.
//DropdownMenu::DropdownMenu(QWidget *parent, QMenu *menu, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap) //DropdownMenu::DropdownMenu(QWidget *parent, QMenu *menu, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap)
//, _st(st) //, _st(st) {
//, _menu(this, menu, _st.menu) { // _menu = setOwnedWidget(object_ptr<Ui::Menu>(this, menu, _st.menu));
// init(); // init();
// //
// for (auto action : actions()) { // for (auto action : actions()) {
@ -45,8 +45,6 @@ DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : Inn
void DropdownMenu::init() { void DropdownMenu::init() {
InnerDropdown::setHiddenCallback([this] { hideFinish(); }); InnerDropdown::setHiddenCallback([this] { hideFinish(); });
setOwnedWidget(_menu);
_menu->setResizedCallback([this] { resizeToContent(); }); _menu->setResizedCallback([this] { resizeToContent(); });
_menu->setActivatedCallback([this](QAction *action, int actionTop, TriggeredSource source) { _menu->setActivatedCallback([this](QAction *action, int actionTop, TriggeredSource source) {
handleActivated(action, actionTop, source); handleActivated(action, actionTop, source);

View File

@ -100,7 +100,7 @@ private:
const style::DropdownMenu &_st; const style::DropdownMenu &_st;
base::lambda<void()> _hiddenCallback; base::lambda<void()> _hiddenCallback;
object_ptr<Ui::Menu> _menu; QPointer<Ui::Menu> _menu;
// Not ready with submenus yet. // Not ready with submenus yet.
//using Submenus = QMap<QAction*, SubmenuPointer>; //using Submenus = QMap<QAction*, SubmenuPointer>;

View File

@ -49,13 +49,15 @@ InnerDropdown::InnerDropdown(QWidget *parent, const style::InnerDropdown &st) :
hide(); hide();
} }
void InnerDropdown::setOwnedWidget(TWidget *widget) { QPointer<TWidget> InnerDropdown::doSetOwnedWidget(object_ptr<TWidget> widget) {
auto result = QPointer<TWidget>(widget);
connect(widget, SIGNAL(heightUpdated()), this, SLOT(onWidgetHeightUpdated())); connect(widget, SIGNAL(heightUpdated()), this, SLOT(onWidgetHeightUpdated()));
auto container = _scroll->setOwnedWidget(object_ptr<Container>(_scroll, widget, _st)); auto container = _scroll->setOwnedWidget(object_ptr<Container>(_scroll, std::move(widget), _st));
container->resizeToWidth(_scroll->width()); container->resizeToWidth(_scroll->width());
container->moveToLeft(0, 0); container->moveToLeft(0, 0);
container->show(); container->show();
widget->show(); result->show();
return result;
} }
void InnerDropdown::setMaxHeight(int newMaxHeight) { void InnerDropdown::setMaxHeight(int newMaxHeight) {
@ -320,15 +322,15 @@ int InnerDropdown::resizeGetHeight(int newWidth) {
return newHeight; return newHeight;
} }
InnerDropdown::Container::Container(QWidget *parent, TWidget *child, const style::InnerDropdown &st) : TWidget(parent), _st(st) { InnerDropdown::Container::Container(QWidget *parent, object_ptr<TWidget> child, const style::InnerDropdown &st) : TWidget(parent)
child->setParent(this); , _child(std::move(child))
child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); , _st(st) {
_child->setParent(this);
_child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top());
} }
void InnerDropdown::Container::setVisibleTopBottom(int visibleTop, int visibleBottom) { void InnerDropdown::Container::setVisibleTopBottom(int visibleTop, int visibleBottom) {
if (auto child = static_cast<TWidget*>(children().front())) { _child->setVisibleTopBottom(visibleTop - _st.scrollPadding.top(), visibleBottom - _st.scrollPadding.top());
child->setVisibleTopBottom(visibleTop - _st.scrollPadding.top(), visibleBottom - _st.scrollPadding.top());
}
} }
void InnerDropdown::Container::resizeToContent() { void InnerDropdown::Container::resizeToContent() {
@ -346,11 +348,9 @@ void InnerDropdown::Container::resizeToContent() {
int InnerDropdown::Container::resizeGetHeight(int newWidth) { int InnerDropdown::Container::resizeGetHeight(int newWidth) {
auto innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right(); auto innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right();
auto result = _st.scrollPadding.top() + _st.scrollPadding.bottom(); auto result = _st.scrollPadding.top() + _st.scrollPadding.bottom();
if (auto child = static_cast<TWidget*>(children().front())) { _child->resizeToWidth(innerWidth);
child->resizeToWidth(innerWidth); _child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top());
child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); result += _child->height();
result += child->height();
}
return result; return result;
} }

View File

@ -33,7 +33,11 @@ class InnerDropdown : public TWidget {
public: public:
InnerDropdown(QWidget *parent, const style::InnerDropdown &st = st::defaultInnerDropdown); InnerDropdown(QWidget *parent, const style::InnerDropdown &st = st::defaultInnerDropdown);
void setOwnedWidget(TWidget *widget); template <typename Widget>
QPointer<Widget> setOwnedWidget(object_ptr<Widget> widget) {
auto result = doSetOwnedWidget(std::move(widget));
return QPointer<Widget>(static_cast<Widget*>(result.data()));
}
bool overlaps(const QRect &globalRect) { bool overlaps(const QRect &globalRect) {
if (isHidden() || _a_show.animating() || _a_opacity.animating()) return false; if (isHidden() || _a_show.animating() || _a_opacity.animating()) return false;
@ -90,6 +94,7 @@ private slots:
} }
private: private:
QPointer<TWidget> doSetOwnedWidget(object_ptr<TWidget> widget);
QImage grabForPanelAnimation(); QImage grabForPanelAnimation();
void startShowAnimation(); void startShowAnimation();
void startOpacityAnimation(bool hiding); void startOpacityAnimation(bool hiding);
@ -128,7 +133,7 @@ private:
class InnerDropdown::Container : public TWidget { class InnerDropdown::Container : public TWidget {
public: public:
Container(QWidget *parent, TWidget *child, const style::InnerDropdown &st); Container(QWidget *parent, object_ptr<TWidget> child, const style::InnerDropdown &st);
void setVisibleTopBottom(int visibleTop, int visibleBottom) override; void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
void resizeToContent(); void resizeToContent();
@ -138,6 +143,7 @@ protected:
private: private:
const style::InnerDropdown &_st; const style::InnerDropdown &_st;
object_ptr<TWidget> _child;
}; };