Handle checkbox toggle

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2025-03-19 01:17:25 +00:00
parent 8577f58fe3
commit 900579eea6
No known key found for this signature in database
GPG Key ID: 5E39D70B4C93C38E
24 changed files with 185 additions and 94 deletions

View File

@ -44,7 +44,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
}; };
} }
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry) ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(const QModelIndex& entry)
{ {
auto& pack = *m_packs[entry.row()]; auto& pack = *m_packs[entry.row()];
auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile(); auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
@ -62,7 +62,7 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en
return { pack, versions, loaders }; return { pack, versions, loaders };
} }
ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(QModelIndex& entry) ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(const QModelIndex& entry)
{ {
auto& pack = *m_packs[entry.row()]; auto& pack = *m_packs[entry.row()];
return { pack }; return { pack };

View File

@ -39,8 +39,8 @@ class ModModel : public ResourceModel {
public slots: public slots:
ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::SearchArgs createSearchArguments() override;
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) override;
protected: protected:
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0;

View File

@ -59,7 +59,6 @@ namespace ResourceDownload {
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance)
{ {
connect(m_ui->resourceFilterButton, &QPushButton::clicked, this, &ModPage::filterMods); connect(m_ui->resourceFilterButton, &QPushButton::clicked, this, &ModPage::filterMods);
connect(m_ui->packView, &QListView::doubleClicked, this, &ModPage::onResourceSelected);
} }
void ModPage::setFilterWidget(unique_qobject_ptr<ModFilterWidget>& widget) void ModPage::setFilterWidget(unique_qobject_ptr<ModFilterWidget>& widget)

View File

@ -35,7 +35,7 @@ class ModPage : public ResourcePage {
page->setFilterWidget(filter_widget); page->setFilterWidget(filter_widget);
model->setFilter(page->getFilter()); model->setFilter(page->getFilter());
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList); connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi); connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
return page; return page;

View File

@ -192,7 +192,7 @@ void ResourceModel::search()
runSearchJob(job); runSearchJob(job);
} }
void ResourceModel::loadEntry(QModelIndex& entry) void ResourceModel::loadEntry(const QModelIndex& entry)
{ {
auto const& pack = m_packs[entry.row()]; auto const& pack = m_packs[entry.row()];
@ -503,7 +503,7 @@ void ResourceModel::versionRequestSucceeded(QJsonDocument& doc, ModPlatform::Ind
return; return;
} }
emit versionListUpdated(); emit versionListUpdated(index);
} }
void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index) void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
@ -530,7 +530,7 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe
return; return;
} }
emit projectInfoUpdated(); emit projectInfoUpdated(index);
} }
void ResourceModel::addPack(ModPlatform::IndexedPack::Ptr pack, void ResourceModel::addPack(ModPlatform::IndexedPack::Ptr pack,

View File

@ -80,17 +80,17 @@ class ResourceModel : public QAbstractListModel {
virtual ResourceAPI::SearchArgs createSearchArguments() = 0; virtual ResourceAPI::SearchArgs createSearchArguments() = 0;
virtual ResourceAPI::SearchCallbacks createSearchCallbacks() { return {}; } virtual ResourceAPI::SearchCallbacks createSearchCallbacks() { return {}; }
virtual ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) = 0; virtual ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) = 0;
virtual ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(QModelIndex&) { return {}; } virtual ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(const QModelIndex&) { return {}; }
virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0; virtual ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) = 0;
virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) { return {}; } virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(const QModelIndex&) { return {}; }
/** Requests the API for more entries. */ /** Requests the API for more entries. */
virtual void search(); virtual void search();
/** Applies any processing / extra requests needed to fully load the specified entry's information. */ /** Applies any processing / extra requests needed to fully load the specified entry's information. */
virtual void loadEntry(QModelIndex&); virtual void loadEntry(const QModelIndex&);
/** Schedule a refresh, clearing the current state. */ /** Schedule a refresh, clearing the current state. */
void refresh(); void refresh();
@ -170,8 +170,8 @@ class ResourceModel : public QAbstractListModel {
void infoRequestSucceeded(QJsonDocument&, ModPlatform::IndexedPack&, const QModelIndex&); void infoRequestSucceeded(QJsonDocument&, ModPlatform::IndexedPack&, const QModelIndex&);
signals: signals:
void versionListUpdated(); void versionListUpdated(const QModelIndex& index);
void projectInfoUpdated(); void projectInfoUpdated(const QModelIndex& index);
}; };
} // namespace ResourceDownload } // namespace ResourceDownload

View File

@ -20,13 +20,13 @@ ResourceAPI::SearchArgs ResourcePackResourceModel::createSearchArguments()
return { ModPlatform::ResourceType::RESOURCE_PACK, m_next_search_offset, m_search_term, sort }; return { ModPlatform::ResourceType::RESOURCE_PACK, m_next_search_offset, m_search_term, sort };
} }
ResourceAPI::VersionSearchArgs ResourcePackResourceModel::createVersionsArguments(QModelIndex& entry) ResourceAPI::VersionSearchArgs ResourcePackResourceModel::createVersionsArguments(const QModelIndex& entry)
{ {
auto& pack = m_packs[entry.row()]; auto& pack = m_packs[entry.row()];
return { *pack }; return { *pack };
} }
ResourceAPI::ProjectInfoArgs ResourcePackResourceModel::createInfoArguments(QModelIndex& entry) ResourceAPI::ProjectInfoArgs ResourcePackResourceModel::createInfoArguments(const QModelIndex& entry)
{ {
auto& pack = m_packs[entry.row()]; auto& pack = m_packs[entry.row()];
return { *pack }; return { *pack };

View File

@ -31,8 +31,8 @@ class ResourcePackResourceModel : public ResourceModel {
public slots: public slots:
ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::SearchArgs createSearchArguments() override;
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) override;
protected: protected:
const BaseInstance& m_base_instance; const BaseInstance& m_base_instance;

View File

@ -14,9 +14,7 @@
namespace ResourceDownload { namespace ResourceDownload {
ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance)
{ {}
connect(m_ui->packView, &QListView::doubleClicked, this, &ResourcePackResourcePage::onResourceSelected);
}
/******** Callbacks to events in the UI (set up in the derived classes) ********/ /******** Callbacks to events in the UI (set up in the derived classes) ********/

View File

@ -25,7 +25,7 @@ class ResourcePackResourcePage : public ResourcePage {
auto page = new T(dialog, instance); auto page = new T(dialog, instance);
auto model = static_cast<ResourcePackResourceModel*>(page->getModel()); auto model = static_cast<ResourcePackResourceModel*>(page->getModel());
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList); connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi); connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
return page; return page;

View File

@ -78,10 +78,14 @@ ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& base_in
m_ui->verticalLayout->insertWidget(1, &m_fetchProgress); m_ui->verticalLayout->insertWidget(1, &m_fetchProgress);
m_ui->packView->setItemDelegate(new ProjectItemDelegate(this)); auto delegate = new ProjectItemDelegate(this);
m_ui->packView->setItemDelegate(delegate);
m_ui->packView->installEventFilter(this); m_ui->packView->installEventFilter(this);
connect(m_ui->packDescription, &QTextBrowser::anchorClicked, this, &ResourcePage::openUrl); connect(m_ui->packDescription, &QTextBrowser::anchorClicked, this, &ResourcePage::openUrl);
connect(m_ui->packView, &QListView::doubleClicked, this, &ResourcePage::onToggle);
connect(delegate, &ProjectItemDelegate::checkboxClicked, this, &ResourcePage::onToggle);
} }
ResourcePage::~ResourcePage() ResourcePage::~ResourcePage()
@ -177,8 +181,11 @@ ModPlatform::IndexedPack::Ptr ResourcePage::getCurrentPack() const
return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack::Ptr>(); return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack::Ptr>();
} }
void ResourcePage::updateUi() void ResourcePage::updateUi(const QModelIndex& index)
{ {
if (index != m_ui->packView->currentIndex())
return;
auto current_pack = getCurrentPack(); auto current_pack = getCurrentPack();
if (!current_pack) { if (!current_pack) {
m_ui->packDescription->setHtml({}); m_ui->packDescription->setHtml({});
@ -268,39 +275,48 @@ void ResourcePage::updateSelectionButton()
} }
} }
void ResourcePage::updateVersionList() void ResourcePage::versionListUpdated(const QModelIndex& index)
{ {
auto current_pack = getCurrentPack(); if (index == m_ui->packView->currentIndex()) {
auto current_pack = getCurrentPack();
m_ui->versionSelectionBox->blockSignals(true); m_ui->versionSelectionBox->blockSignals(true);
m_ui->versionSelectionBox->clear(); m_ui->versionSelectionBox->clear();
m_ui->versionSelectionBox->blockSignals(false); m_ui->versionSelectionBox->blockSignals(false);
if (current_pack) { if (current_pack) {
auto installedVersion = m_model->getInstalledPackVersion(current_pack); auto installedVersion = m_model->getInstalledPackVersion(current_pack);
for (int i = 0; i < current_pack->versions.size(); i++) { for (int i = 0; i < current_pack->versions.size(); i++) {
auto& version = current_pack->versions[i]; auto& version = current_pack->versions[i];
if (!m_model->checkVersionFilters(version)) if (!m_model->checkVersionFilters(version))
continue; continue;
auto versionText = version.version; auto versionText = version.version;
if (version.version_type.isValid()) { if (version.version_type.isValid()) {
versionText += QString(" [%1]").arg(version.version_type.toString()); versionText += QString(" [%1]").arg(version.version_type.toString());
}
if (version.fileId == installedVersion) {
versionText += tr(" [installed]", "Mod version select");
}
m_ui->versionSelectionBox->addItem(versionText, QVariant(i));
} }
if (version.fileId == installedVersion) {
versionText += tr(" [installed]", "Mod version select");
}
m_ui->versionSelectionBox->addItem(versionText, QVariant(i));
} }
} if (m_ui->versionSelectionBox->count() == 0) {
if (m_ui->versionSelectionBox->count() == 0) { m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1));
m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1)); m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :(")); }
}
updateSelectionButton(); if (m_enableQueue.contains(index.row())) {
m_enableQueue.remove(index.row());
onToggle(index);
} else
updateSelectionButton();
} else if (m_enableQueue.contains(index.row())) {
m_enableQueue.remove(index.row());
onToggle(index);
}
} }
void ResourcePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelIndex prev) void ResourcePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelIndex prev)
@ -318,16 +334,20 @@ void ResourcePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
request_load = true; request_load = true;
} else { } else {
updateVersionList(); versionListUpdated(curr);
} }
if (current_pack && !current_pack->extraDataLoaded) if (current_pack && !current_pack->extraDataLoaded)
request_load = true; request_load = true;
// we are already requesting this
if (m_enableQueue.contains(curr.row()))
request_load = false;
if (request_load) if (request_load)
m_model->loadEntry(curr); m_model->loadEntry(curr);
updateUi(); updateUi(curr);
} }
void ResourcePage::onVersionSelectionChanged(int index) void ResourcePage::onVersionSelectionChanged(int index)
@ -385,6 +405,41 @@ void ResourcePage::onResourceSelected()
m_ui->packView->repaint(); m_ui->packView->repaint();
} }
void ResourcePage::onToggle(const QModelIndex& index)
{
const bool is_selected = index == m_ui->packView->currentIndex();
auto pack = m_model->data(index, Qt::UserRole).value<ModPlatform::IndexedPack::Ptr>();
if (pack->versionsLoaded) {
if (pack->isAnyVersionSelected())
removeResourceFromDialog(pack->name);
else {
auto version = std::find_if(pack->versions.begin(), pack->versions.end(), [this](const ModPlatform::IndexedVersion& version) {
return m_model->checkVersionFilters(version);
});
if (version != pack->versions.end())
addResourceToDialog(pack, *version);
}
if (is_selected)
updateSelectionButton();
// force update
QVariant variant;
variant.setValue(pack);
m_model->setData(index, variant, Qt::UserRole);
} else {
// the model is just 1 dimensional so this is fine
m_enableQueue.insert(index.row());
// we can't be sure that this hasn't already been requested...
// but this does the job well enough and there's not much point preventing edgecases
if (!is_selected)
m_model->loadEntry(index);
}
}
void ResourcePage::openUrl(const QUrl& url) void ResourcePage::openUrl(const QUrl& url)
{ {
// do not allow other url schemes for security reasons // do not allow other url schemes for security reasons

View File

@ -71,9 +71,9 @@ class ResourcePage : public QWidget, public BasePage {
void addSortings(); void addSortings();
public slots: public slots:
virtual void updateUi(); virtual void updateUi(const QModelIndex& index);
virtual void updateSelectionButton(); virtual void updateSelectionButton();
virtual void updateVersionList(); virtual void versionListUpdated(const QModelIndex& index);
void addResourceToDialog(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&); void addResourceToDialog(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&);
void removeResourceFromDialog(const QString& pack_name); void removeResourceFromDialog(const QString& pack_name);
@ -91,6 +91,7 @@ class ResourcePage : public QWidget, public BasePage {
void onSelectionChanged(QModelIndex first, QModelIndex second); void onSelectionChanged(QModelIndex first, QModelIndex second);
void onVersionSelectionChanged(int index); void onVersionSelectionChanged(int index);
void onResourceSelected(); void onResourceSelected();
void onToggle(const QModelIndex& index);
// NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12 // NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12
@ -115,6 +116,8 @@ class ResourcePage : public QWidget, public BasePage {
QTimer m_searchTimer; QTimer m_searchTimer;
bool m_doNotJumpToMod = false; bool m_doNotJumpToMod = false;
QSet<int> m_enableQueue;
}; };
} // namespace ResourceDownload } // namespace ResourceDownload

View File

@ -20,13 +20,13 @@ ResourceAPI::SearchArgs ShaderPackResourceModel::createSearchArguments()
return { ModPlatform::ResourceType::SHADER_PACK, m_next_search_offset, m_search_term, sort }; return { ModPlatform::ResourceType::SHADER_PACK, m_next_search_offset, m_search_term, sort };
} }
ResourceAPI::VersionSearchArgs ShaderPackResourceModel::createVersionsArguments(QModelIndex& entry) ResourceAPI::VersionSearchArgs ShaderPackResourceModel::createVersionsArguments(const QModelIndex& entry)
{ {
auto& pack = m_packs[entry.row()]; auto& pack = m_packs[entry.row()];
return { *pack }; return { *pack };
} }
ResourceAPI::ProjectInfoArgs ShaderPackResourceModel::createInfoArguments(QModelIndex& entry) ResourceAPI::ProjectInfoArgs ShaderPackResourceModel::createInfoArguments(const QModelIndex& entry)
{ {
auto& pack = m_packs[entry.row()]; auto& pack = m_packs[entry.row()];
return { *pack }; return { *pack };

View File

@ -31,8 +31,8 @@ class ShaderPackResourceModel : public ResourceModel {
public slots: public slots:
ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::SearchArgs createSearchArguments() override;
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override; ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) override;
protected: protected:
const BaseInstance& m_base_instance; const BaseInstance& m_base_instance;

View File

@ -15,10 +15,7 @@
namespace ResourceDownload { namespace ResourceDownload {
ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) {}
{
connect(m_ui->packView, &QListView::doubleClicked, this, &ShaderPackResourcePage::onResourceSelected);
}
/******** Callbacks to events in the UI (set up in the derived classes) ********/ /******** Callbacks to events in the UI (set up in the derived classes) ********/

View File

@ -25,7 +25,7 @@ class ShaderPackResourcePage : public ResourcePage {
auto page = new T(dialog, instance); auto page = new T(dialog, instance);
auto model = static_cast<ShaderPackResourceModel*>(page->getModel()); auto model = static_cast<ShaderPackResourceModel*>(page->getModel());
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList); connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi); connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
return page; return page;

View File

@ -70,7 +70,7 @@ ResourceAPI::SearchArgs TexturePackResourceModel::createSearchArguments()
return args; return args;
} }
ResourceAPI::VersionSearchArgs TexturePackResourceModel::createVersionsArguments(QModelIndex& entry) ResourceAPI::VersionSearchArgs TexturePackResourceModel::createVersionsArguments(const QModelIndex& entry)
{ {
auto args = ResourcePackResourceModel::createVersionsArguments(entry); auto args = ResourcePackResourceModel::createVersionsArguments(entry);
if (!m_version_list->isLoaded()) { if (!m_version_list->isLoaded()) {

View File

@ -18,7 +18,7 @@ class TexturePackResourceModel : public ResourcePackResourceModel {
[[nodiscard]] inline ::Version maximumTexturePackVersion() const { return { "1.6" }; } [[nodiscard]] inline ::Version maximumTexturePackVersion() const { return { "1.6" }; }
ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::SearchArgs createSearchArguments() override;
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
protected: protected:
Meta::VersionList::Ptr m_version_list; Meta::VersionList::Ptr m_version_list;

View File

@ -27,7 +27,7 @@ class TexturePackResourcePage : public ResourcePackResourcePage {
auto page = new T(dialog, instance); auto page = new T(dialog, instance);
auto model = static_cast<TexturePackResourceModel*>(page->getModel()); auto model = static_cast<TexturePackResourceModel*>(page->getModel());
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList); connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi); connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
return page; return page;
@ -39,10 +39,7 @@ class TexturePackResourcePage : public ResourcePackResourcePage {
[[nodiscard]] inline QString resourceString() const override { return tr("texture pack"); } [[nodiscard]] inline QString resourceString() const override { return tr("texture pack"); }
protected: protected:
TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance) : ResourcePackResourcePage(dialog, instance) TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance) : ResourcePackResourcePage(dialog, instance) {}
{
connect(m_ui->packView, &QListView::doubleClicked, this, &TexturePackResourcePage::onResourceSelected);
}
}; };
} // namespace ResourceDownload } // namespace ResourceDownload

View File

@ -122,7 +122,7 @@ ResourceAPI::SearchArgs FlameTexturePackModel::createSearchArguments()
return args; return args;
} }
ResourceAPI::VersionSearchArgs FlameTexturePackModel::createVersionsArguments(QModelIndex& entry) ResourceAPI::VersionSearchArgs FlameTexturePackModel::createVersionsArguments(const QModelIndex& entry)
{ {
auto args = TexturePackResourceModel::createVersionsArguments(entry); auto args = TexturePackResourceModel::createVersionsArguments(entry);

View File

@ -69,7 +69,7 @@ class FlameTexturePackModel : public TexturePackResourceModel {
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
ResourceAPI::SearchArgs createSearchArguments() override; ResourceAPI::SearchArgs createSearchArguments() override;
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override; ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
}; };

View File

@ -16,34 +16,20 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
QStyleOptionViewItem opt(option); QStyleOptionViewItem opt(option);
initStyleOption(&opt, index); initStyleOption(&opt, index);
auto rect = opt.rect;
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style(); const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
auto rect = opt.rect;
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
if (option.state & QStyle::State_Selected) if (option.state & QStyle::State_Selected)
painter->setPen(opt.palette.highlightedText().color()); painter->setPen(opt.palette.highlightedText().color());
if (opt.features & QStyleOptionViewItem::HasCheckIndicator) { if (opt.features & QStyleOptionViewItem::HasCheckIndicator) {
// 5px will be the typical margin with 48px icon size QStyleOptionViewItem checkboxOpt = makeCheckboxStyleOption(opt, style);
// we don't want the checkbox to be all over the place
rect.translate(5, 0);
QStyleOptionViewItem checkboxOpt = opt;
checkboxOpt.state &= ~QStyle::State_HasFocus;
if (checkboxOpt.checkState == Qt::Checked)
checkboxOpt.state |= QStyle::State_On;
QRect checkboxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &checkboxOpt, opt.widget);
checkboxOpt.rect =
QRect(rect.x(), rect.y() + (rect.height() / 2 - checkboxRect.height() / 2), checkboxRect.width(), checkboxRect.height());
style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &checkboxOpt, painter, opt.widget); style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &checkboxOpt, painter, opt.widget);
rect.setX(rect.x() + checkboxRect.width()); rect.setX(checkboxOpt.rect.right());
} }
// The default icon size will be a square (and height is usually the lower value). // The default icon size will be a square (and height is usually the lower value).
@ -141,3 +127,51 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
painter->restore(); painter->restore();
} }
bool ProjectItemDelegate::editorEvent(QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& index)
{
if (!(event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonDblClick))
return false;
auto mouseEvent = (QMouseEvent*)event;
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
const QStyleOptionViewItem checkboxOpt = makeCheckboxStyleOption(opt, style);
if (!checkboxOpt.rect.contains(mouseEvent->x(), mouseEvent->y()))
return false;
// swallow other events
// (prevents item being selected or double click action triggering)
if (event->type() != QEvent::MouseButtonRelease)
return true;
emit checkboxClicked(index);
return true;
}
QStyleOptionViewItem ProjectItemDelegate::makeCheckboxStyleOption(const QStyleOptionViewItem& opt, const QStyle* style) const
{
QStyleOptionViewItem checkboxOpt = opt;
checkboxOpt.state &= ~QStyle::State_HasFocus;
if (checkboxOpt.checkState == Qt::Checked)
checkboxOpt.state |= QStyle::State_On;
QRect checkboxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &checkboxOpt, opt.widget);
// 5px is the typical top margin for image
// we don't want the checkboxes to be all over the place :)
checkboxOpt.rect = QRect(opt.rect.x() + 5, opt.rect.y() + (opt.rect.height() / 2 - checkboxRect.height() / 2), checkboxRect.width(),
checkboxRect.height());
return checkboxOpt;
}

View File

@ -6,7 +6,7 @@
enum UserDataTypes { enum UserDataTypes {
TITLE = 257, // QString TITLE = 257, // QString
DESCRIPTION = 258, // QString DESCRIPTION = 258, // QString
INSTALLED = 260 // bool INSTALLED = 259 // bool
}; };
/** This is an item delegate composed of: /** This is an item delegate composed of:
@ -21,4 +21,12 @@ class ProjectItemDelegate final : public QStyledItemDelegate {
ProjectItemDelegate(QWidget* parent); ProjectItemDelegate(QWidget* parent);
void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const override; void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const override;
bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) override;
signals:
void checkboxClicked(const QModelIndex& index);
private:
QStyleOptionViewItem makeCheckboxStyleOption(const QStyleOptionViewItem& opt, const QStyle* style) const;
}; };

View File

@ -43,8 +43,8 @@ class DummyResourceModel : public ResourceModel {
[[nodiscard]] auto metaEntryBase() const -> QString override { return ""; } [[nodiscard]] auto metaEntryBase() const -> QString override { return ""; }
ResourceAPI::SearchArgs createSearchArguments() override { return {}; } ResourceAPI::SearchArgs createSearchArguments() override { return {}; }
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override { return {}; } ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override { return {}; }
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override { return {}; } ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) override { return {}; }
QJsonArray documentToArray(QJsonDocument& doc) const override { return doc.object().value("hits").toArray(); } QJsonArray documentToArray(QJsonDocument& doc) const override { return doc.object().value("hits").toArray(); }