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 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<Profile::GroupMembersWidget>(this, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem));
_membersDropdown->resizeToWidth(st::membersInnerWidth);
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());

View file

@ -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<Ui::Menu>(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<Ui::Menu>(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);

View file

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

View file

@ -49,13 +49,15 @@ InnerDropdown::InnerDropdown(QWidget *parent, const style::InnerDropdown &st) :
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()));
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->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<TWidget> 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<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() {
@ -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<TWidget*>(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;
}

View file

@ -33,7 +33,11 @@ class InnerDropdown : public TWidget {
public:
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) {
if (isHidden() || _a_show.animating() || _a_opacity.animating()) return false;
@ -90,6 +94,7 @@ private slots:
}
private:
QPointer<TWidget> doSetOwnedWidget(object_ptr<TWidget> 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<TWidget> 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<TWidget> _child;
};