added colon emote popup for ffz and bttv

This commit is contained in:
fourtf
2020-08-15 18:59:17 +02:00
parent 6781482485
commit f7237dccdd
26 changed files with 700 additions and 251 deletions
@@ -0,0 +1,48 @@
#include "widgets/dialogs/switcher/GenericItemDelegate.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
@@ -0,0 +1,22 @@
#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
+22
View File
@@ -0,0 +1,22 @@
#include "GenericListItem.hpp"
namespace chatterino {
const QSize GenericListItem::ICON_SIZE(32, 32);
GenericListItem *GenericListItem::fromVariant(const QVariant &variant)
{
// See https://stackoverflow.com/a/44503822 .
return static_cast<GenericListItem *>(variant.value<void *>());
}
GenericListItem::GenericListItem()
{
}
GenericListItem::GenericListItem(const QIcon &icon)
: icon_(icon)
{
}
} // namespace chatterino
+44
View File
@@ -0,0 +1,44 @@
#pragma once
namespace chatterino {
class GenericListItem
{
public:
/**
* @brief Attempt to obtain an GenericListItem * from the passed QVariant.
*
* @param variant variant to try to convert to GenericListItem *
*
* @return an GenericListItem * if the QVariant could be converted,
* or nullptr if the variant did not contain GenericListItem *
*/
static GenericListItem *fromVariant(const QVariant &variant);
virtual ~GenericListItem() = default;
GenericListItem();
/**
* @param icon icon to be displayed in the switcher list
*/
GenericListItem(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;
};
} // namespace chatterino
// This allows us to store GenericListItem * as a QVariant
Q_DECLARE_METATYPE(chatterino::GenericListItem *);
+51
View File
@@ -0,0 +1,51 @@
#include "GenericListModel.hpp"
namespace chatterino {
GenericListModel::GenericListModel(QWidget *parent)
: QAbstractListModel(parent)
{
}
int GenericListModel::rowCount(const QModelIndex &parent) const
{
return this->items_.size();
}
QVariant GenericListModel::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 GenericListModel::addItem(std::unique_ptr<GenericListItem> 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 GenericListModel::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
+49
View File
@@ -0,0 +1,49 @@
#include "widgets/listview/GenericListItem.hpp"
namespace chatterino {
class GenericListModel : public QAbstractListModel
{
public:
GenericListModel(QWidget *parent = nullptr);
/**
* @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 GenericListItem * is always returned.
*
* @param index index of item to fetch data from
* @param role (not used)
*
* @return GenericListItem * (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<GenericListItem> item);
/**
* @brief Clears this QuickSwitcherModel of all items. This will delete all
* GenericListItems added after the last invokation of
* QuickSwitcherModel::clear (and invalidate their pointers).
*/
void clear();
private:
std::vector<std::unique_ptr<GenericListItem>> items_;
};
} // namespace chatterino
+114
View File
@@ -0,0 +1,114 @@
#include "GenericListView.hpp"
#include "singletons/Theme.hpp"
#include "widgets/listview/GenericListModel.hpp"
namespace chatterino {
GenericListView::GenericListView()
: itemDelegate_(this)
{
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setSelectionBehavior(QAbstractItemView::SelectItems);
this->setItemDelegate(&this->itemDelegate_);
QObject::connect(
this, &QListView::clicked, this, [this](const QModelIndex &index) {
auto *item = GenericListItem::fromVariant(index.data());
item->action();
emit this->closeRequested();
});
}
void GenericListView::setModel(QAbstractItemModel *model)
{
auto casted = dynamic_cast<GenericListModel *>(model);
assert(casted);
this->setModel(casted);
}
void GenericListView::setModel(GenericListModel *model)
{
this->model_ = model;
QListView::setModel(model);
}
bool GenericListView::eventFilter(QObject * /*watched*/, QEvent *event)
{
if (!this->model_)
return false;
if (event->type() == QEvent::KeyPress)
{
auto *keyEvent = static_cast<QKeyEvent *>(event);
int key = keyEvent->key();
const QModelIndex &curIdx = this->currentIndex();
const int curRow = curIdx.row();
const int count = this->model_->rowCount(curIdx);
if (key == Qt::Key_Down || key == Qt::Key_Tab)
{
if (count <= 0)
return true;
const int newRow = (curRow + 1) % count;
this->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->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->currentIndex();
auto *item = GenericListItem::fromVariant(index.data());
item->action();
emit this->closeRequested();
return true;
}
else
{
return false;
}
}
return false;
}
void GenericListView::refreshTheme(const Theme &theme)
{
const QString textCol = theme.window.text.name();
const QString bgCol = theme.window.background.name();
const QString selCol =
(theme.isLightTheme()
? "#68B1FF" // Copied from Theme::splits.input.styleSheet
: 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->setStyleSheet(listStyle);
}
} // namespace chatterino
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <QListView>
#include "widgets/listview/GenericItemDelegate.hpp"
#include "widgets/listview/GenericListItem.hpp"
namespace chatterino {
class GenericListModel;
class Theme;
class GenericListView : public QListView
{
Q_OBJECT
public:
GenericListView();
virtual void setModel(QAbstractItemModel *model) override;
void setModel(GenericListModel *);
bool eventFilter(QObject *watched, QEvent *event) override;
GenericListModel *model_{};
SwitcherItemDelegate itemDelegate_;
void refreshTheme(const Theme &theme);
signals:
void closeRequested();
};
} // namespace chatterino