NOISSUE Support ATLauncher optional mods

This commit is contained in:
Jamie Mansfield 2021-05-28 15:03:14 +01:00
parent 8179a89103
commit 74311a54cf
No known key found for this signature in database
GPG Key ID: 36F61598F39F67B0
10 changed files with 305 additions and 3 deletions

View File

@ -457,16 +457,31 @@ void PackInstallTask::extractConfigs()
void PackInstallTask::downloadMods() void PackInstallTask::downloadMods()
{ {
qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId(); qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId();
QVector<ATLauncher::VersionMod> optionalMods;
for (const auto& mod : m_version.mods) {
if (mod.optional) {
optionalMods.push_back(mod);
}
}
// Select optional mods, if pack contains any
QVector<QString> selectedMods;
if (!optionalMods.isEmpty()) {
setStatus(tr("Selecting optional mods..."));
selectedMods = m_support->chooseOptionalMods(optionalMods);
}
setStatus(tr("Downloading mods...")); setStatus(tr("Downloading mods..."));
jarmods.clear(); jarmods.clear();
jobPtr.reset(new NetJob(tr("Mod download"))); jobPtr.reset(new NetJob(tr("Mod download")));
for(const auto& mod : m_version.mods) { for(const auto& mod : m_version.mods) {
// skip non-client mods // skip non-client mods
if (!mod.client) continue; if(!mod.client) continue;
// skip optional mods for now // skip optional mods that were not selected
if(mod.optional) continue; if(mod.optional && !selectedMods.contains(mod.name)) continue;
QString url; QString url;
switch(mod.download) { switch(mod.download) {

View File

@ -18,6 +18,11 @@ namespace ATLauncher {
class MULTIMC_LOGIC_EXPORT UserInteractionSupport { class MULTIMC_LOGIC_EXPORT UserInteractionSupport {
public: public:
/**
* Requests a user interaction to select which optional mods should be installed.
*/
virtual QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) = 0;
/** /**
* Requests a user interaction to select a component version from a given version list * Requests a user interaction to select a component version from a given version list
* and constrained to a given Minecraft version. * and constrained to a given Minecraft version.

View File

@ -143,7 +143,10 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) {
p.decompFile = Json::requireString(obj, "decompFile"); p.decompFile = Json::requireString(obj, "decompFile");
} }
p.description = Json::ensureString(obj, QString("description"), "");
p.optional = Json::ensureBoolean(obj, QString("optional"), false); p.optional = Json::ensureBoolean(obj, QString("optional"), false);
p.recommended = Json::ensureBoolean(obj, QString("recommended"), false);
p.selected = Json::ensureBoolean(obj, QString("selected"), false);
p.client = Json::ensureBoolean(obj, QString("client"), false); p.client = Json::ensureBoolean(obj, QString("client"), false);
} }

View File

@ -86,7 +86,10 @@ struct VersionMod
QString decompType_raw; QString decompType_raw;
QString decompFile; QString decompFile;
QString description;
bool optional; bool optional;
bool recommended;
bool selected;
bool client; bool client;
}; };

View File

@ -129,6 +129,8 @@ SET(MULTIMC_SOURCES
pages/modplatform/atlauncher/AtlFilterModel.h pages/modplatform/atlauncher/AtlFilterModel.h
pages/modplatform/atlauncher/AtlListModel.cpp pages/modplatform/atlauncher/AtlListModel.cpp
pages/modplatform/atlauncher/AtlListModel.h pages/modplatform/atlauncher/AtlListModel.h
pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
pages/modplatform/atlauncher/AtlOptionalModDialog.h
pages/modplatform/atlauncher/AtlPage.cpp pages/modplatform/atlauncher/AtlPage.cpp
pages/modplatform/atlauncher/AtlPage.h pages/modplatform/atlauncher/AtlPage.h
@ -278,6 +280,9 @@ SET(MULTIMC_UIS
pages/modplatform/technic/TechnicPage.ui pages/modplatform/technic/TechnicPage.ui
pages/modplatform/ImportPage.ui pages/modplatform/ImportPage.ui
# Platform Dialogs
pages/modplatform/atlauncher/AtlOptionalModDialog.ui
# Dialogs # Dialogs
dialogs/CopyInstanceDialog.ui dialogs/CopyInstanceDialog.ui
dialogs/NewComponentDialog.ui dialogs/NewComponentDialog.ui

View File

@ -0,0 +1,138 @@
#include "AtlOptionalModDialog.h"
#include "ui_AtlOptionalModDialog.h"
AtlOptionalModListModel::AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
: QAbstractListModel(parent), m_mods(mods) {
for (const auto& mod : mods) {
m_selection[mod.name] = mod.selected;
}
}
QVector<QString> AtlOptionalModListModel::getResult() {
QVector<QString> result;
for (const auto& mod : m_mods) {
if (m_selection[mod.name]) {
result.push_back(mod.name);
}
}
return result;
}
int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
return m_mods.size();
}
int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
// Enabled, Name, Description
return 3;
}
QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
auto row = index.row();
auto mod = m_mods.at(row);
if (role == Qt::DisplayRole) {
if (index.column() == NameColumn) {
return mod.name;
}
if (index.column() == DescriptionColumn) {
return mod.description;
}
}
else if (role == Qt::ToolTipRole) {
if (index.column() == DescriptionColumn) {
return mod.description;
}
}
else if (role == Qt::CheckStateRole) {
if (index.column() == EnabledColumn) {
return m_selection[mod.name] ? Qt::Checked : Qt::Unchecked;
}
}
return QVariant();
}
bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if (role == Qt::CheckStateRole) {
auto row = index.row();
auto mod = m_mods.at(row);
// toggle the state
m_selection[mod.name] = !m_selection[mod.name];
emit dataChanged(AtlOptionalModListModel::index(index.row(), EnabledColumn),
AtlOptionalModListModel::index(index.row(), EnabledColumn));
return true;
}
return false;
}
QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case EnabledColumn:
return QString();
case NameColumn:
return QString("Name");
case DescriptionColumn:
return QString("Description");
}
}
return QVariant();
}
Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const {
auto flags = QAbstractListModel::flags(index);
if (index.isValid() && index.column() == EnabledColumn) {
flags |= Qt::ItemIsUserCheckable;
}
return flags;
}
void AtlOptionalModListModel::selectRecommended() {
for (const auto& mod : m_mods) {
m_selection[mod.name] = mod.recommended;
}
emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
}
void AtlOptionalModListModel::clearAll() {
for (const auto& mod : m_mods) {
m_selection[mod.name] = false;
}
emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
}
AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
: QDialog(parent), ui(new Ui::AtlOptionalModDialog) {
ui->setupUi(this);
listModel = new AtlOptionalModListModel(this, mods);
ui->treeView->setModel(listModel);
ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->treeView->header()->setSectionResizeMode(
AtlOptionalModListModel::NameColumn, QHeaderView::ResizeToContents);
ui->treeView->header()->setSectionResizeMode(
AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch);
connect(ui->selectRecommendedButton, &QPushButton::pressed,
listModel, &AtlOptionalModListModel::selectRecommended);
connect(ui->clearAllButton, &QPushButton::pressed,
listModel, &AtlOptionalModListModel::clearAll);
}
AtlOptionalModDialog::~AtlOptionalModDialog() {
delete ui;
}

View File

@ -0,0 +1,60 @@
#pragma once
#include <QDialog>
#include <QAbstractListModel>
#include "modplatform/atlauncher/ATLPackIndex.h"
namespace Ui {
class AtlOptionalModDialog;
}
class AtlOptionalModListModel : public QAbstractListModel {
Q_OBJECT
public:
enum Columns
{
EnabledColumn = 0,
NameColumn,
DescriptionColumn,
};
AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
QVector<QString> getResult();
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
public slots:
void selectRecommended();
void clearAll();
private:
QVector<ATLauncher::VersionMod> m_mods;
QMap<QString, bool> m_selection;
};
class AtlOptionalModDialog : public QDialog {
Q_OBJECT
public:
AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
~AtlOptionalModDialog() override;
QVector<QString> getResult() {
return listModel->getResult();
}
private:
Ui::AtlOptionalModDialog *ui;
AtlOptionalModListModel *listModel;
};

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AtlOptionalModDialog</class>
<widget class="QDialog" name="AtlOptionalModDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Mods To Install</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="3">
<widget class="QPushButton" name="installButton">
<property name="text">
<string>Install</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="selectRecommendedButton">
<property name="text">
<string>Select Recommended</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="shareCodeButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Use Share Code</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="clearAllButton">
<property name="text">
<string>Clear All</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="ModListView" name="treeView"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ModListView</class>
<extends>QTreeView</extends>
<header>widgets/ModListView.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -2,6 +2,7 @@
#include "ui_AtlPage.h" #include "ui_AtlPage.h"
#include "dialogs/NewInstanceDialog.h" #include "dialogs/NewInstanceDialog.h"
#include "AtlOptionalModDialog.h"
#include <modplatform/atlauncher/ATLPackInstallTask.h> #include <modplatform/atlauncher/ATLPackInstallTask.h>
#include <BuildConfig.h> #include <BuildConfig.h>
#include <dialogs/VersionSelectDialog.h> #include <dialogs/VersionSelectDialog.h>
@ -131,6 +132,12 @@ void AtlPage::onVersionSelectionChanged(QString data)
suggestCurrent(); suggestCurrent();
} }
QVector<QString> AtlPage::chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) {
AtlOptionalModDialog optionalModDialog(this, mods);
optionalModDialog.exec();
return optionalModDialog.getResult();
}
QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) {
VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false); VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false);
if (minecraftVersion != Q_NULLPTR) { if (minecraftVersion != Q_NULLPTR) {

View File

@ -63,6 +63,7 @@ private:
void suggestCurrent(); void suggestCurrent();
QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override;
QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) override;
private slots: private slots:
void triggerSearch(); void triggerSearch();