diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 34092be62..5495675bd 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -84,6 +84,7 @@ constexpr auto kTabbedSelectorToggleTooltipTimeoutMs = 3000; constexpr auto kTabbedSelectorToggleTooltipCount = 3; constexpr auto kScrollToVoiceAfterScrolledMs = 1000; constexpr auto kSkipRepaintWhileScrollMs = 100; +constexpr auto kShowMembersDropdownTimeoutMs = 300; ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() { return [](ChannelData *channel, MsgId msgId) { @@ -1834,6 +1835,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re destroyUnreadBar(); destroyPinnedBar(); + _membersDropdown.destroy(); _scrollToAnimation.finish(); _history = _migrated = nullptr; _peer = nullptr; @@ -3868,7 +3870,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) { if (_membersDropdown) { _membersDropdown->otherEnter(); } else if (!_membersDropdownShowTimer.isActive()) { - _membersDropdownShowTimer.start(300); + _membersDropdownShowTimer.start(kShowMembersDropdownTimeoutMs); } } else if (_membersDropdown) { _membersDropdown->otherLeave(); @@ -3878,7 +3880,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) { void HistoryWidget::onMembersDropdownShow() { if (!_membersDropdown) { _membersDropdown.create(this, st::membersInnerDropdown); - _membersDropdown->setOwnedWidget(new Profile::GroupMembersWidget(_membersDropdown, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem)); + _membersDropdown->setOwnedWidget(object_ptr(this, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem)); _membersDropdown->resizeToWidth(st::membersInnerWidth); _membersDropdown->setMaxHeight(countMembersDropdownHeightMax()); diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp index c64fa1277..58dc7c73a 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp @@ -23,15 +23,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Ui { DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap) -, _st(st) -, _menu(this, _st.menu) { +, _st(st) { + _menu = setOwnedWidget(object_ptr(this, _st.menu)); init(); } // Not ready with submenus yet. //DropdownMenu::DropdownMenu(QWidget *parent, QMenu *menu, const style::DropdownMenu &st) : InnerDropdown(parent, st.wrap) -//, _st(st) -//, _menu(this, menu, _st.menu) { +//, _st(st) { +// _menu = setOwnedWidget(object_ptr(this, menu, _st.menu)); // init(); // // for (auto action : actions()) { @@ -45,8 +45,6 @@ DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : Inn void DropdownMenu::init() { InnerDropdown::setHiddenCallback([this] { hideFinish(); }); - setOwnedWidget(_menu); - _menu->setResizedCallback([this] { resizeToContent(); }); _menu->setActivatedCallback([this](QAction *action, int actionTop, TriggeredSource source) { handleActivated(action, actionTop, source); diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h index 9fff13e3f..bf3001352 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h @@ -100,7 +100,7 @@ private: const style::DropdownMenu &_st; base::lambda _hiddenCallback; - object_ptr _menu; + QPointer _menu; // Not ready with submenus yet. //using Submenus = QMap; diff --git a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp index aade32426..efe7cba4a 100644 --- a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp +++ b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp @@ -49,13 +49,15 @@ InnerDropdown::InnerDropdown(QWidget *parent, const style::InnerDropdown &st) : hide(); } -void InnerDropdown::setOwnedWidget(TWidget *widget) { +QPointer InnerDropdown::doSetOwnedWidget(object_ptr widget) { + auto result = QPointer(widget); connect(widget, SIGNAL(heightUpdated()), this, SLOT(onWidgetHeightUpdated())); - auto container = _scroll->setOwnedWidget(object_ptr(_scroll, widget, _st)); + auto container = _scroll->setOwnedWidget(object_ptr(_scroll, std::move(widget), _st)); container->resizeToWidth(_scroll->width()); container->moveToLeft(0, 0); container->show(); - widget->show(); + result->show(); + return result; } void InnerDropdown::setMaxHeight(int newMaxHeight) { @@ -320,15 +322,15 @@ int InnerDropdown::resizeGetHeight(int newWidth) { return newHeight; } -InnerDropdown::Container::Container(QWidget *parent, TWidget *child, const style::InnerDropdown &st) : TWidget(parent), _st(st) { - child->setParent(this); - child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); +InnerDropdown::Container::Container(QWidget *parent, object_ptr child, const style::InnerDropdown &st) : TWidget(parent) +, _child(std::move(child)) +, _st(st) { + _child->setParent(this); + _child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); } void InnerDropdown::Container::setVisibleTopBottom(int visibleTop, int visibleBottom) { - if (auto child = static_cast(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() { @@ -346,11 +348,9 @@ void InnerDropdown::Container::resizeToContent() { int InnerDropdown::Container::resizeGetHeight(int newWidth) { auto innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right(); auto result = _st.scrollPadding.top() + _st.scrollPadding.bottom(); - if (auto child = static_cast(children().front())) { - child->resizeToWidth(innerWidth); - child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); - result += child->height(); - } + _child->resizeToWidth(innerWidth); + _child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top()); + result += _child->height(); return result; } diff --git a/Telegram/SourceFiles/ui/widgets/inner_dropdown.h b/Telegram/SourceFiles/ui/widgets/inner_dropdown.h index c4e238458..1bdcbceda 100644 --- a/Telegram/SourceFiles/ui/widgets/inner_dropdown.h +++ b/Telegram/SourceFiles/ui/widgets/inner_dropdown.h @@ -33,7 +33,11 @@ class InnerDropdown : public TWidget { public: InnerDropdown(QWidget *parent, const style::InnerDropdown &st = st::defaultInnerDropdown); - void setOwnedWidget(TWidget *widget); + template + QPointer setOwnedWidget(object_ptr widget) { + auto result = doSetOwnedWidget(std::move(widget)); + return QPointer(static_cast(result.data())); + } bool overlaps(const QRect &globalRect) { if (isHidden() || _a_show.animating() || _a_opacity.animating()) return false; @@ -90,6 +94,7 @@ private slots: } private: + QPointer doSetOwnedWidget(object_ptr widget); QImage grabForPanelAnimation(); void startShowAnimation(); void startOpacityAnimation(bool hiding); @@ -128,7 +133,7 @@ private: class InnerDropdown::Container : public TWidget { public: - Container(QWidget *parent, TWidget *child, const style::InnerDropdown &st); + Container(QWidget *parent, object_ptr child, const style::InnerDropdown &st); void setVisibleTopBottom(int visibleTop, int visibleBottom) override; void resizeToContent(); @@ -138,6 +143,7 @@ protected: private: const style::InnerDropdown &_st; + object_ptr _child; };