Add ResourceTable class

Base class to be used to display items in a table
This commit is contained in:
WarmUpTill 2024-04-26 21:48:51 +02:00 committed by WarmUpTill
parent 54f1051456
commit 530fbdd282
5 changed files with 318 additions and 0 deletions

View File

@ -191,6 +191,10 @@ target_sources(
lib/utils/regex-config.hpp
lib/utils/resizing-text-edit.cpp
lib/utils/resizing-text-edit.hpp
lib/utils/resource-table.cpp
lib/utils/resource-table.hpp
lib/utils/resource-table-hotkey-handler.cpp
lib/utils/resource-table-hotkey-handler.hpp
lib/utils/scene-selection.cpp
lib/utils/scene-selection.hpp
lib/utils/scene-switch-helpers.cpp

View File

@ -0,0 +1,70 @@
#include "resource-table-hotkey-handler.hpp"
#include <QKeyEvent>
#include <QWidget>
#include <unordered_map>
namespace advss {
void RegisterHotkeyFunction(QWidget *widget, Qt::Key key,
std::function<void()> func)
{
ResourceTabHotkeyHandler::Instance()->RegisterHandler(widget, key,
func);
}
void DeregisterHotkeyFunctions(QWidget *widget)
{
ResourceTabHotkeyHandler::Instance()->Deregister(widget);
}
ResourceTabHotkeyHandler *ResourceTabHotkeyHandler::Instance()
{
static ResourceTabHotkeyHandler handler;
return &handler;
}
void ResourceTabHotkeyHandler::RegisterHandler(QWidget *widget, Qt::Key key,
std::function<void()> func)
{
std::lock_guard<std::mutex> lock(_mutex);
_callbacks.emplace(widget, CallbackData{key, func});
widget->installEventFilter(this);
}
void ResourceTabHotkeyHandler::Deregister(QWidget *widget)
{
std::lock_guard<std::mutex> lock(_mutex);
_callbacks.erase(widget);
}
bool ResourceTabHotkeyHandler::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() != QEvent::KeyPress) {
return QObject::eventFilter(obj, event);
}
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
auto pressedKey = keyEvent->key();
std::lock_guard<std::mutex> lock(_mutex);
auto it = _callbacks.find(obj);
if (it == _callbacks.end()) {
return QObject::eventFilter(obj, event);
}
auto current = it;
while (current != _callbacks.end() && current->first == it->first) {
auto &[_, cbData] = *current;
if (pressedKey != cbData.key) {
++current;
continue;
}
cbData.func();
++current;
continue;
}
return QObject::eventFilter(obj, event);
}
} // namespace advss

View File

@ -0,0 +1,37 @@
#pragma once
#include "export-symbol-helper.hpp"
#include <map>
#include <mutex>
#include <QEvent>
#include <QObject>
namespace advss {
EXPORT void RegisterHotkeyFunction(QWidget *, Qt::Key,
std::function<void()> func);
EXPORT void DeregisterHotkeyFunctions(QWidget *);
class ResourceTabHotkeyHandler : public QObject {
Q_OBJECT
public:
static ResourceTabHotkeyHandler *Instance();
void RegisterHandler(QWidget *, Qt::Key, std::function<void()> func);
void Deregister(QWidget *);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
struct CallbackData {
Qt::Key key;
std::function<void()> func;
};
ResourceTabHotkeyHandler() : QObject(){};
std::multimap<QObject *, CallbackData> _callbacks;
std::mutex _mutex;
};
} // namespace advss

View File

@ -0,0 +1,157 @@
#include "resource-table.hpp"
#include "plugin-state-helpers.hpp"
#include "resource-table-hotkey-handler.hpp"
#include "ui-helpers.hpp"
#include <QGridLayout>
#include <QHeaderView>
namespace advss {
ResourceTable::ResourceTable(QTabWidget *parent, const QString &help,
const QString &addToolTip,
const QString &removeToolTip,
const QStringList &headers,
const std::function<void()> &openSettings)
: QWidget(parent),
_table(new QTableWidget()),
_add(new QPushButton()),
_remove(new QPushButton()),
_help(new QLabel(help))
{
_add->setMaximumWidth(22);
_add->setProperty("themeID",
QVariant(QString::fromUtf8("addIconSmall")));
_add->setFlat(true);
_add->setToolTip(addToolTip);
_remove->setMaximumWidth(22);
_remove->setProperty("themeID",
QVariant(QString::fromUtf8("removeIconSmall")));
_remove->setFlat(true);
_remove->setToolTip(removeToolTip);
_help->setWordWrap(true);
_help->setAlignment(Qt::AlignCenter);
_table->setColumnCount(headers.size());
_table->horizontalHeader()->setSectionResizeMode(
QHeaderView::ResizeMode::Interactive);
_table->setHorizontalHeaderLabels(headers);
_table->verticalHeader()->hide();
_table->setCornerButtonEnabled(false);
_table->setShowGrid(false);
_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
_table->setSelectionBehavior(QAbstractItemView::SelectRows);
auto helpAndTableLayout = new QGridLayout();
helpAndTableLayout->setContentsMargins(0, 0, 0, 0);
helpAndTableLayout->addWidget(_table, 0, 0);
helpAndTableLayout->addWidget(_help, 0, 0, Qt::AlignCenter);
auto controlLayout = new QHBoxLayout;
controlLayout->setContentsMargins(0, 0, 0, 0);
controlLayout->addWidget(_add);
controlLayout->addWidget(_remove);
controlLayout->addStretch();
auto layout = new QVBoxLayout();
layout->addLayout(helpAndTableLayout);
layout->addLayout(controlLayout);
setLayout(layout);
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
QWidget::connect(_table, &QTableWidget::cellDoubleClicked,
[openSettings]() { openSettings(); });
RegisterHotkeyFunction(this, Qt::Key_F2, openSettings);
RegisterHotkeyFunction(this, Qt::Key_Delete, [this]() { Remove(); });
}
ResourceTable::~ResourceTable()
{
DeregisterHotkeyFunctions(this);
}
void ResourceTable::SetHelpVisible(bool visible) const
{
_help->setVisible(visible);
}
void ResourceTable::HighlightAddButton(bool enable)
{
_add->disconnect(_highlightConnection);
if (enable && HighlightUIElementsEnabled()) {
_highlightConnection = PulseWidget(_add, QColor(Qt::green));
}
}
void ResourceTable::resizeEvent(QResizeEvent *)
{
const auto columnCount = _table->columnCount();
const auto columnSize = (_table->width() - 1) / columnCount;
for (int i = 0; i < columnCount; ++i) {
_table->horizontalHeader()->resizeSection(i, columnSize);
}
}
void AddItemTableRow(QTableWidget *table, const QStringList &cellLabels)
{
int row = table->rowCount();
table->setRowCount(row + 1);
int col = 0;
for (const auto &cellLabel : cellLabels) {
auto *item = new QTableWidgetItem(cellLabel);
item->setToolTip(cellLabel);
table->setItem(row, col, item);
col++;
}
table->sortByColumn(0, Qt::AscendingOrder);
}
void UpdateItemTableRow(QTableWidget *table, int row,
const QStringList &cellLabels)
{
int col = 1; // Skip the name cell
for (const auto &cellLabel : cellLabels) {
auto item = table->item(row, col);
item->setText(cellLabel);
item->setToolTip(cellLabel);
col++;
}
}
void RenameItemTableRow(QTableWidget *table, const QString &oldName,
const QString &newName)
{
for (int row = 0; row < table->rowCount(); row++) {
auto item = table->item(row, 0);
if (!item) {
continue;
}
if (item->text() == oldName) {
item->setText(newName);
table->sortByColumn(0, Qt::AscendingOrder);
return;
}
}
assert(false);
}
void RemoveItemTableRow(QTableWidget *table, const QString &name)
{
for (int row = 0; row < table->rowCount(); ++row) {
auto item = table->item(row, 0);
if (item && item->text() == name) {
table->removeRow(row);
return;
}
}
table->sortByColumn(0, Qt::AscendingOrder);
}
} // namespace advss

View File

@ -0,0 +1,50 @@
#pragma once
#include "export-symbol-helper.hpp"
#include <QLabel>
#include <QPushButton>
#include <QString>
#include <QTableWidget>
class QResizeEvent;
namespace advss {
class ADVSS_EXPORT ResourceTable : public QWidget {
Q_OBJECT
public:
ResourceTable(QTabWidget *parent, const QString &help,
const QString &addToolTip, const QString &removeToolTip,
const QStringList &headers,
const std::function<void()> &openSettings);
virtual ~ResourceTable();
QTableWidget *Table() const { return _table; }
void SetHelpVisible(bool) const;
void HighlightAddButton(bool);
protected slots:
virtual void Add() {}
virtual void Remove() {}
protected:
void resizeEvent(QResizeEvent *event);
private:
QTableWidget *_table;
QPushButton *_add;
QPushButton *_remove;
QLabel *_help;
QMetaObject::Connection _highlightConnection;
};
EXPORT void AddItemTableRow(QTableWidget *table, const QStringList &cells);
EXPORT void UpdateItemTableRow(QTableWidget *table, int row,
const QStringList &cells);
EXPORT void RenameItemTableRow(QTableWidget *table, const QString &oldName,
const QString &newName);
EXPORT void RemoveItemTableRow(QTableWidget *table, const QString &name);
} // namespace advss