Files
chatterino2/src/widgets/dialogs/switcher/QuickSwitcherPopup.cpp
pajlada fdb0a1582c SplitContainer refactor (#4261)
* Remove unused include util/Helpers.hpp

* SplitContainer::setTag fix parameter naming

* autofy/constify where possible

* More const auto ptr magicifying

* Make SplitNode::Type an enum class

* Move QuickSwitcherPopup includes from header to source file

* Remove unused DropRegion code

* use empty() instead of size() == 0

* Add curly braces everywhere

* Remove useless reinterpret_cast

It was casting Node* to Node*

* Clarify that the connect is QObject::connect

* SplitContainer::setSelected fix parameter naming

* Rename function variables to remove unneccesary underscore

Also move addSpacing parameter out of the layout function

* emplace_back where possible

* Name parameters

* Remove ineffective const from return type

* Make node getters const

* Flatten Node::releaseSplit

* Rename in-function variable to match code style

* [ACTUAL CODE CHANGE/MOVE] Move clamp logic to its own function

* name params

* applyFromDescriptorRecursively: rename node param to baseNode

* [ACTUAL CODE CHANGE/MOVE] Remove the many overloads for append/insertSplit

This utilizes the C++20 designed initializers aggregate initialization feature

* Remove unused includes

* [ACTUAL CODE CHANGE] Clean up dragging logic

There's no need to keep a pointer around to which split is being
dragged, it's already stored in the QDropEvent source()

* UNRELATED .clang-tidy: Only suggest UPPER_CASE for constant global variables

* Remove unused SplitContainer::getSplitCount function

* Use std::max in Node's clamp function

* Remove test code

* DraggedSplit.hpp: remove unused include

* Split `setDraggingSplit` into two functions, `startDraggingSplit` and `stopDraggingSplit`
2022-12-25 11:09:25 +00:00

166 lines
5.2 KiB
C++

#include "widgets/dialogs/switcher/QuickSwitcherPopup.hpp"
#include "Application.hpp"
#include "common/Channel.hpp"
#include "singletons/Theme.hpp"
#include "singletons/WindowManager.hpp"
#include "util/LayoutCreator.hpp"
#include "widgets/dialogs/switcher/NewPopupItem.hpp"
#include "widgets/dialogs/switcher/NewTabItem.hpp"
#include "widgets/dialogs/switcher/SwitchSplitItem.hpp"
#include "widgets/helper/NotebookTab.hpp"
#include "widgets/listview/GenericListView.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/splits/Split.hpp"
#include "widgets/splits/SplitContainer.hpp"
#include "widgets/Window.hpp"
namespace chatterino {
namespace {
QList<SplitContainer *> openPages()
{
QList<SplitContainer *> pages;
auto &nb = getApp()->windows->getMainWindow().getNotebook();
for (int i = 0; i < nb.getPageCount(); ++i)
{
pages.append(static_cast<SplitContainer *>(nb.getPageAt(i)));
}
return pages;
}
} // namespace
const QSize QuickSwitcherPopup::MINIMUM_SIZE(500, 300);
QuickSwitcherPopup::QuickSwitcherPopup(QWidget *parent)
: BasePopup({BaseWindow::Flags::Frameless, BaseWindow::Flags::TopMost,
BaseWindow::DisableLayoutSave},
parent)
, switcherModel_(this)
{
this->setWindowFlag(Qt::Dialog);
this->setActionOnFocusLoss(BaseWindow::ActionOnFocusLoss::Delete);
this->setMinimumSize(QuickSwitcherPopup::MINIMUM_SIZE);
this->initWidgets();
this->setStayInScreenRect(true);
const QRect geom = parent->geometry();
// This places the popup in the middle of the parent widget
this->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,
this->size(), geom));
this->themeChangedEvent();
this->installEventFilter(this->ui_.list);
}
void QuickSwitcherPopup::initWidgets()
{
LayoutCreator<QWidget> creator(this->BaseWindow::getLayoutContainer());
auto vbox = creator.setLayoutType<QVBoxLayout>();
{
auto lineEdit = vbox.emplace<QLineEdit>().assign(&this->ui_.searchEdit);
lineEdit->setPlaceholderText("Jump to a channel or open a new one");
QObject::connect(this->ui_.searchEdit, &QLineEdit::textChanged, this,
&QuickSwitcherPopup::updateSuggestions);
}
{
auto listView = vbox.emplace<GenericListView>().assign(&this->ui_.list);
listView->setModel(&this->switcherModel_);
QObject::connect(listView.getElement(),
&GenericListView::closeRequested, this, [this] {
this->close();
});
this->ui_.searchEdit->installEventFilter(listView.getElement());
}
}
void QuickSwitcherPopup::updateSuggestions(const QString &text)
{
this->switcherModel_.clear();
// Add items for navigating to different splits
for (auto *sc : openPages())
{
const QString &tabTitle = sc->getTab()->getTitle();
const auto splits = sc->getSplits();
// First, check for splits on this page
for (auto *split : splits)
{
if (split->getChannel()->getName().contains(text,
Qt::CaseInsensitive))
{
auto item = std::make_unique<SwitchSplitItem>(sc, split);
this->switcherModel_.addItem(std::move(item));
// We want to continue the outer loop so we need a goto
goto nextPage;
}
}
// Then check if tab title matches
if (tabTitle.contains(text, Qt::CaseInsensitive))
{
auto item = std::make_unique<SwitchSplitItem>(sc);
this->switcherModel_.addItem(std::move(item));
continue;
}
nextPage:;
}
// Add item for opening a channel in a new tab or new popup
if (!text.isEmpty())
{
auto newTabItem = std::make_unique<NewTabItem>(text);
this->switcherModel_.addItem(std::move(newTabItem));
auto newPopupItem = std::make_unique<NewPopupItem>(text);
this->switcherModel_.addItem(std::move(newPopupItem));
}
const auto &startIdx = this->switcherModel_.index(0);
this->ui_.list->setCurrentIndex(startIdx);
/*
* Timeout interval 0 means the call will be delayed until all window events
* have been processed (cf. https://doc.qt.io/qt-5/qtimer.html#interval-prop).
*/
QTimer::singleShot(0, [this] {
this->adjustSize();
});
}
void QuickSwitcherPopup::themeChangedEvent()
{
BasePopup::themeChangedEvent();
const QString textCol = this->theme->window.text.name();
const QString bgCol = this->theme->window.background.name();
const QString selCol =
(this->theme->isLightTheme()
? "#68B1FF" // Copied from Theme::splits.input.styleSheet
: this->theme->tabs.selected.backgrounds.regular.color().name());
const QString listStyle =
QString(
"color: %1; background-color: %2; selection-background-color: %3")
.arg(textCol)
.arg(bgCol)
.arg(selCol);
this->ui_.searchEdit->setStyleSheet(this->theme->splits.input.styleSheet);
this->ui_.list->refreshTheme(*this->theme);
}
} // namespace chatterino