added colon emote popup for ffz and bttv
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
#include "widgets/dialogs/switcher/AbstractSwitcherItem.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
const QSize AbstractSwitcherItem::ICON_SIZE(32, 32);
|
||||
|
||||
AbstractSwitcherItem *AbstractSwitcherItem::fromVariant(const QVariant &variant)
|
||||
{
|
||||
// See https://stackoverflow.com/a/44503822 .
|
||||
return static_cast<AbstractSwitcherItem *>(variant.value<void *>());
|
||||
}
|
||||
|
||||
AbstractSwitcherItem::AbstractSwitcherItem(const QIcon &icon)
|
||||
: icon_(icon)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,45 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/listview/GenericListItem.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class AbstractSwitcherItem
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Attempt to obtain an AbstractSwitcherItem * from the passed QVariant.
|
||||
*
|
||||
* @param variant variant to try to convert to AbstractSwitcherItem *
|
||||
*
|
||||
* @return an AbstractSwitcherItem * if the QVariant could be converted,
|
||||
* or nullptr if the variant did not contain AbstractSwitcherItem *
|
||||
*/
|
||||
static AbstractSwitcherItem *fromVariant(const QVariant &variant);
|
||||
|
||||
virtual ~AbstractSwitcherItem() = default;
|
||||
|
||||
/**
|
||||
* @brief Since all switcher items are required to have an icon, we require it
|
||||
* in the base class constructor.
|
||||
*
|
||||
* @param icon icon to be displayed in the switcher list
|
||||
*/
|
||||
AbstractSwitcherItem(const QIcon &icon);
|
||||
|
||||
/**
|
||||
* @brief Action to perform when this item is activated. Must be implemented in
|
||||
* subclasses.
|
||||
*/
|
||||
virtual void action() = 0;
|
||||
|
||||
virtual void paint(QPainter *painter, const QRect &rect) const = 0;
|
||||
virtual QSize sizeHint(const QRect &rect) const = 0;
|
||||
|
||||
protected:
|
||||
QIcon icon_;
|
||||
static const QSize ICON_SIZE;
|
||||
};
|
||||
using AbstractSwitcherItem = GenericListItem;
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
// This allows us to store AbstractSwitcherItem * as a QVariant
|
||||
Q_DECLARE_METATYPE(chatterino::AbstractSwitcherItem *);
|
||||
|
||||
@@ -2,51 +2,4 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
QuickSwitcherModel::QuickSwitcherModel(QWidget *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int QuickSwitcherModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return this->items_.size();
|
||||
}
|
||||
|
||||
QVariant QuickSwitcherModel::data(const QModelIndex &index,
|
||||
int /* role */) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (index.row() >= this->items_.size())
|
||||
return QVariant();
|
||||
|
||||
auto item = this->items_[index.row()].get();
|
||||
// See https://stackoverflow.com/a/44503822 .
|
||||
return QVariant::fromValue(static_cast<void *>(item));
|
||||
}
|
||||
|
||||
void QuickSwitcherModel::addItem(std::unique_ptr<AbstractSwitcherItem> item)
|
||||
{
|
||||
// {begin,end}InsertRows needs to be called to notify attached views
|
||||
this->beginInsertRows(QModelIndex(), this->items_.size(),
|
||||
this->items_.size());
|
||||
this->items_.push_back(std::move(item));
|
||||
this->endInsertRows();
|
||||
}
|
||||
|
||||
void QuickSwitcherModel::clear()
|
||||
{
|
||||
if (this->items_.empty())
|
||||
return;
|
||||
|
||||
// {begin,end}RemoveRows needs to be called to notify attached views
|
||||
this->beginRemoveRows(QModelIndex(), 0, this->items_.size() - 1);
|
||||
|
||||
// clear
|
||||
this->items_.clear();
|
||||
|
||||
this->endRemoveRows();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,52 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "widgets/dialogs/switcher/AbstractSwitcherItem.hpp"
|
||||
#include "widgets/listview/GenericListModel.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class QuickSwitcherModel : public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
QuickSwitcherModel(QWidget *parent = nullptr);
|
||||
using QuickSwitcherModel = GenericListModel;
|
||||
|
||||
/**
|
||||
* @brief Reimplements QAbstractItemModel::rowCount.
|
||||
*
|
||||
* @return number of items currrently present in this model
|
||||
*/
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
/**
|
||||
* @brief Reimplements QAbstractItemModel::data. Currently, the role parameter
|
||||
* is not used and an AbstractSwitcherItem * is always returned.
|
||||
*
|
||||
* @param index index of item to fetch data from
|
||||
* @param role (not used)
|
||||
*
|
||||
* @return AbstractSwitcherItem * (wrapped as QVariant) at index
|
||||
*/
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
|
||||
/**
|
||||
* @brief Add an item to this QuickSwitcherModel. It will be displayed in
|
||||
* attached views.
|
||||
*
|
||||
* NOTE: The model will take ownership of the pointer. In particular,
|
||||
* the same item should not be passed to multiple QuickSwitcherModels.
|
||||
*
|
||||
* @param item item to add to the model
|
||||
*/
|
||||
void addItem(std::unique_ptr<AbstractSwitcherItem> item);
|
||||
|
||||
/**
|
||||
* @brief Clears this QuickSwitcherModel of all items. This will delete all
|
||||
* AbstractSwitcherItems added after the last invokation of
|
||||
* QuickSwitcherModel::clear (and invalidate their pointers).
|
||||
*/
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<AbstractSwitcherItem>> items_;
|
||||
};
|
||||
} // namespace chatterino
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "widgets/dialogs/switcher/NewTabItem.hpp"
|
||||
#include "widgets/dialogs/switcher/SwitchSplitItem.hpp"
|
||||
#include "widgets/helper/NotebookTab.hpp"
|
||||
#include "widgets/listview/GenericListView.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
@@ -36,7 +37,6 @@ QuickSwitcherPopup::QuickSwitcherPopup(QWidget *parent)
|
||||
BaseWindow::Flags::TopMost},
|
||||
parent)
|
||||
, switcherModel_(this)
|
||||
, switcherItemDelegate_(this)
|
||||
{
|
||||
this->setWindowFlag(Qt::Dialog);
|
||||
this->setActionOnFocusLoss(BaseWindow::ActionOnFocusLoss::Delete);
|
||||
@@ -51,10 +51,8 @@ QuickSwitcherPopup::QuickSwitcherPopup(QWidget *parent)
|
||||
this->size(), geom));
|
||||
|
||||
this->themeChangedEvent();
|
||||
}
|
||||
|
||||
QuickSwitcherPopup::~QuickSwitcherPopup()
|
||||
{
|
||||
this->installEventFilter(this->ui_.list);
|
||||
}
|
||||
|
||||
void QuickSwitcherPopup::initWidgets()
|
||||
@@ -72,24 +70,12 @@ void QuickSwitcherPopup::initWidgets()
|
||||
}
|
||||
|
||||
{
|
||||
vbox.emplace<QListView>().assign(&this->ui_.list);
|
||||
this->ui_.list->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
this->ui_.list->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
this->ui_.list->setModel(&this->switcherModel_);
|
||||
this->ui_.list->setItemDelegate(&this->switcherItemDelegate_);
|
||||
auto listView = vbox.emplace<GenericListView>().assign(&this->ui_.list);
|
||||
listView->setModel(&this->switcherModel_);
|
||||
|
||||
/*
|
||||
* I also tried handling key events using the according slots but
|
||||
* it lead to all kind of problems that did not occur with the
|
||||
* eventFilter approach.
|
||||
*/
|
||||
QObject::connect(
|
||||
this->ui_.list, &QListView::clicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
auto *item = AbstractSwitcherItem::fromVariant(index.data());
|
||||
item->action();
|
||||
this->close();
|
||||
});
|
||||
QObject::connect(listView.getElement(),
|
||||
&GenericListView::closeRequested, this,
|
||||
[this] { this->close(); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,61 +131,6 @@ void QuickSwitcherPopup::updateSuggestions(const QString &text)
|
||||
QTimer::singleShot(0, [this] { this->adjustSize(); });
|
||||
}
|
||||
|
||||
bool QuickSwitcherPopup::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
auto *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
int key = keyEvent->key();
|
||||
|
||||
const QModelIndex &curIdx = this->ui_.list->currentIndex();
|
||||
const int curRow = curIdx.row();
|
||||
const int count = this->switcherModel_.rowCount(curIdx);
|
||||
|
||||
if (key == Qt::Key_Down || key == Qt::Key_Tab)
|
||||
{
|
||||
if (count <= 0)
|
||||
return true;
|
||||
|
||||
const int newRow = (curRow + 1) % count;
|
||||
|
||||
this->ui_.list->setCurrentIndex(curIdx.siblingAtRow(newRow));
|
||||
return true;
|
||||
}
|
||||
else if (key == Qt::Key_Up || key == Qt::Key_Backtab)
|
||||
{
|
||||
if (count <= 0)
|
||||
return true;
|
||||
|
||||
int newRow = curRow - 1;
|
||||
if (newRow < 0)
|
||||
newRow += count;
|
||||
|
||||
this->ui_.list->setCurrentIndex(curIdx.siblingAtRow(newRow));
|
||||
return true;
|
||||
}
|
||||
else if (key == Qt::Key_Enter || key == Qt::Key_Return)
|
||||
{
|
||||
if (count <= 0)
|
||||
return true;
|
||||
|
||||
const auto index = this->ui_.list->currentIndex();
|
||||
auto *item = AbstractSwitcherItem::fromVariant(index.data());
|
||||
|
||||
item->action();
|
||||
|
||||
this->close();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QuickSwitcherPopup::themeChangedEvent()
|
||||
{
|
||||
BasePopup::themeChangedEvent();
|
||||
@@ -220,7 +151,7 @@ void QuickSwitcherPopup::themeChangedEvent()
|
||||
.arg(selCol);
|
||||
|
||||
this->ui_.searchEdit->setStyleSheet(this->theme->splits.input.styleSheet);
|
||||
this->ui_.list->setStyleSheet(listStyle);
|
||||
this->ui_.list->refreshTheme(*this->theme);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "common/Channel.hpp"
|
||||
#include "widgets/BasePopup.hpp"
|
||||
#include "widgets/dialogs/switcher/QuickSwitcherModel.hpp"
|
||||
#include "widgets/dialogs/switcher/SwitcherItemDelegate.hpp"
|
||||
#include "widgets/splits/Split.hpp"
|
||||
#include "widgets/splits/SplitContainer.hpp"
|
||||
|
||||
@@ -11,6 +10,8 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class GenericListView;
|
||||
|
||||
class QuickSwitcherPopup : public BasePopup
|
||||
{
|
||||
public:
|
||||
@@ -22,10 +23,7 @@ public:
|
||||
*/
|
||||
explicit QuickSwitcherPopup(QWidget *parent = nullptr);
|
||||
|
||||
~QuickSwitcherPopup();
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
virtual void themeChangedEvent() override;
|
||||
|
||||
public slots:
|
||||
@@ -36,11 +34,10 @@ private:
|
||||
|
||||
struct {
|
||||
QLineEdit *searchEdit{};
|
||||
QListView *list{};
|
||||
GenericListView *list{};
|
||||
} ui_;
|
||||
|
||||
QuickSwitcherModel switcherModel_;
|
||||
SwitcherItemDelegate switcherItemDelegate_;
|
||||
|
||||
void initWidgets();
|
||||
};
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "widgets/dialogs/switcher/SwitcherItemDelegate.hpp"
|
||||
|
||||
#include "widgets/dialogs/switcher/AbstractSwitcherItem.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
SwitcherItemDelegate::SwitcherItemDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SwitcherItemDelegate::~SwitcherItemDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
void SwitcherItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
auto *item = AbstractSwitcherItem::fromVariant(index.data());
|
||||
|
||||
if (item)
|
||||
{
|
||||
if (option.state & QStyle::State_Selected)
|
||||
painter->fillRect(option.rect, option.palette.highlight());
|
||||
|
||||
item->paint(painter, option.rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
}
|
||||
|
||||
QSize SwitcherItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
auto *item = AbstractSwitcherItem::fromVariant(index.data());
|
||||
|
||||
if (item)
|
||||
{
|
||||
return item->sizeHint(option.rect);
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class SwitcherItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SwitcherItemDelegate(QObject *parent = nullptr);
|
||||
~SwitcherItemDelegate();
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
Reference in New Issue
Block a user