diff --git a/chatterino.pro b/chatterino.pro index ac3242c54..38168d72e 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -381,7 +381,8 @@ HEADERS += \ src/util/clamp.hpp \ src/widgets/label.hpp \ src/util/combine_path.hpp \ - src/widgets/settingspages/browserextensionpage.hpp + src/widgets/settingspages/browserextensionpage.hpp \ + src/nullableptr.hpp RESOURCES += \ resources/resources.qrc diff --git a/src/nullableptr.hpp b/src/nullableptr.hpp new file mode 100644 index 000000000..f38ecfa5d --- /dev/null +++ b/src/nullableptr.hpp @@ -0,0 +1,59 @@ +#pragma once + +namespace chatterino { + +template +class NullablePtr +{ +public: + NullablePtr() + : element_(nullptr) + { + } + + NullablePtr(T *element) + : element_(element) + { + } + + T *operator->() const + { + assert(this->hasElement()); + + return element_; + } + + T &operator*() const + { + assert(this->hasElement()); + + return *element_; + } + + T *get() const + { + assert(this->hasElement()); + + return this->element_; + } + + bool isNull() const + { + return this->element_ == nullptr; + } + + bool hasElement() const + { + return this->element_ != nullptr; + } + + operator bool() const + { + return this->hasElement(); + } + +private: + T *element_; +}; + +} // namespace chatterino diff --git a/src/widgets/selectchanneldialog.cpp b/src/widgets/selectchanneldialog.cpp index e4731341f..8848e01f5 100644 --- a/src/widgets/selectchanneldialog.cpp +++ b/src/widgets/selectchanneldialog.cpp @@ -16,8 +16,8 @@ namespace chatterino { namespace widgets { -SelectChannelDialog::SelectChannelDialog() - : BaseWindow((QWidget *)nullptr, BaseWindow::EnableCustomFrame) +SelectChannelDialog::SelectChannelDialog(QWidget *parent) + : BaseWindow(parent, BaseWindow::EnableCustomFrame) , selectedChannel(Channel::getEmpty()) { this->setWindowTitle("Select a channel to join"); diff --git a/src/widgets/selectchanneldialog.hpp b/src/widgets/selectchanneldialog.hpp index afb9ee11c..f39b4b0c6 100644 --- a/src/widgets/selectchanneldialog.hpp +++ b/src/widgets/selectchanneldialog.hpp @@ -15,7 +15,7 @@ namespace widgets { class SelectChannelDialog : public BaseWindow { public: - SelectChannelDialog(); + SelectChannelDialog(QWidget *parent = nullptr); void setSelectedChannel(IndirectChannel selectedChannel); IndirectChannel getSelectedChannel() const; diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp index 2659a2b1c..c8c1ab6c8 100644 --- a/src/widgets/split.cpp +++ b/src/widgets/split.cpp @@ -45,7 +45,7 @@ pajlada::Signals::Signal Split::modifierStatusChanged; Qt::KeyboardModifiers Split::modifierStatus = Qt::NoModifier; Split::Split(SplitContainer *parent) - : Split((QWidget *)parent) + : Split(static_cast(parent)) { this->container = parent; } @@ -232,7 +232,13 @@ bool Split::getModerationMode() const void Split::showChangeChannelPopup(const char *dialogTitle, bool empty, std::function callback) { - SelectChannelDialog *dialog = new SelectChannelDialog(); + if (this->selectChannelDialog.hasElement()) { + this->selectChannelDialog->raise(); + + return; + } + + SelectChannelDialog *dialog = new SelectChannelDialog(this); if (!empty) { dialog->setSelectedChannel(this->getIndirectChannel()); } @@ -247,7 +253,9 @@ void Split::showChangeChannelPopup(const char *dialogTitle, bool empty, } callback(dialog->hasSeletedChannel()); + this->selectChannelDialog = nullptr; }); + this->selectChannelDialog = dialog; } void Split::layoutMessages() @@ -362,6 +370,7 @@ void Split::doCloseSplit() void Split::doChangeChannel() { this->showChangeChannelPopup("Change channel", false, [](bool) {}); + auto popup = this->findChildren(); if (popup.size() && popup.at(0)->isVisible() && !popup.at(0)->isFloating()) { popup.at(0)->hide(); diff --git a/src/widgets/split.hpp b/src/widgets/split.hpp index 07051145d..ebbced2dd 100644 --- a/src/widgets/split.hpp +++ b/src/widgets/split.hpp @@ -5,6 +5,7 @@ #include "messages/layouts/messagelayoutelement.hpp" #include "messages/limitedqueuesnapshot.hpp" #include "messages/messageelement.hpp" +#include "nullableptr.hpp" #include "util/serialize-custom.hpp" #include "widgets/basewidget.hpp" #include "widgets/helper/channelview.hpp" @@ -22,6 +23,7 @@ namespace widgets { class SplitContainer; class SplitOverlay; +class SelectChannelDialog; // Each ChatWidget consists of three sub-elements that handle their own part of the chat widget: // ChatWidgetHeader @@ -96,6 +98,8 @@ private: SplitInput input; SplitOverlay *overlay; + NullablePtr selectChannelDialog; + bool moderationMode = false; bool isMouseOver = false;