Merge branch 'develop' into feature/images-for-resource-page

This commit is contained in:
Rachel Powers
2023-05-28 12:01:49 -07:00
120 changed files with 1978 additions and 603 deletions

View File

@ -46,7 +46,6 @@
MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage)
{
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
loadSettings();
updateCheckboxStuff();
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>936</width>
<height>1134</height>
<height>541</height>
</rect>
</property>
<property name="sizePolicy">
@ -39,7 +39,7 @@
</property>
<widget class="QWidget" name="minecraftTab">
<attribute name="title">
<string notr="true">Minecraft</string>
<string notr="true">General</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
@ -111,68 +111,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="nativeLibWorkaroundGroupBox">
<property name="title">
<string>Native library workarounds</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="useNativeGLFWCheck">
<property name="text">
<string>Use system installation of &amp;GLFW</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useNativeOpenALCheck">
<property name="text">
<string>Use system installation of &amp;OpenAL</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="perfomanceGroupBox">
<property name="title">
<string>Performance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="enableFeralGamemodeCheck">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable Feral Interactive's GameMode, to potentially improve gaming performance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable Feral GameMode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableMangoHud">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable MangoHud's advanced performance overlay.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable MangoHud</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useDiscreteGpuCheck">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use the discrete GPU instead of the primary GPU.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use discrete GPU</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gameTimeGroupBox">
<property name="title">
@ -247,6 +185,88 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tweaks</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QGroupBox" name="nativeLibWorkaroundGroupBox">
<property name="title">
<string>Native library workarounds</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QCheckBox" name="useNativeGLFWCheck">
<property name="text">
<string>Use system installation of &amp;GLFW</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useNativeOpenALCheck">
<property name="text">
<string>Use system installation of &amp;OpenAL</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="perfomanceGroupBox">
<property name="title">
<string>Performance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="enableFeralGamemodeCheck">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable Feral Interactive's GameMode, to potentially improve gaming performance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable Feral GameMode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableMangoHud">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable MangoHud's advanced performance overlay.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable MangoHud</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useDiscreteGpuCheck">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use the discrete GPU instead of the primary GPU.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use discrete GPU</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -255,11 +275,6 @@
<tabstop>maximizedCheckBox</tabstop>
<tabstop>windowWidthSpinBox</tabstop>
<tabstop>windowHeightSpinBox</tabstop>
<tabstop>useNativeGLFWCheck</tabstop>
<tabstop>useNativeOpenALCheck</tabstop>
<tabstop>enableFeralGamemodeCheck</tabstop>
<tabstop>enableMangoHud</tabstop>
<tabstop>useDiscreteGpuCheck</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -30,8 +30,6 @@ class NoBigComboBoxStyle : public QProxyStyle {
Q_OBJECT
public:
NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {}
// clang-format off
int styleHint(QStyle::StyleHint hint, const QStyleOption* option = nullptr, const QWidget* widget = nullptr, QStyleHintReturn* returnData = nullptr) const override
{
@ -41,6 +39,37 @@ class NoBigComboBoxStyle : public QProxyStyle {
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
// clang-format on
/**
* Something about QProxyStyle and QStyle objects means they can't be free'd just
* because all the widgets using them are gone.
* They seems to be tied to the QApplicaiton lifecycle.
* So make singletons tied to the lifetime of the application to clean them up and ensure they aren't
* being remade over and over again, thus leaking memory.
*/
public:
static NoBigComboBoxStyle* getInstance(QStyle* style)
{
static QHash<QStyle*, NoBigComboBoxStyle*> s_singleton_instances_ = {};
static std::mutex s_singleton_instances_mutex_;
std::lock_guard<std::mutex> lock(s_singleton_instances_mutex_);
auto inst_iter = s_singleton_instances_.constFind(style);
NoBigComboBoxStyle* inst = nullptr;
if (inst_iter == s_singleton_instances_.constEnd() || *inst_iter == nullptr) {
inst = new NoBigComboBoxStyle(style);
inst->setParent(APPLICATION);
s_singleton_instances_.insert(style, inst);
qDebug() << "QProxyStyle NoBigComboBox created for" << style->objectName() << style;
} else {
inst = *inst_iter;
}
return inst;
}
private:
NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {}
};
ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent)
@ -62,8 +91,10 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi
// NOTE: GTK2 themes crash with the proxy style.
// This seems like an upstream bug, so there's not much else that can be done.
if (!QStyleFactory::keys().contains("gtk2"))
ui->versionsComboBox->setStyle(new NoBigComboBoxStyle(ui->versionsComboBox->style()));
if (!QStyleFactory::keys().contains("gtk2")){
auto comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style());
ui->versionsComboBox->setStyle(comboStyle);
}
ui->reloadButton->setVisible(false);
connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool){

View File

@ -165,7 +165,7 @@ VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent)
auto proxy = new IconProxy(ui->packageView);
proxy->setSourceModel(m_profile.get());
m_filterModel = new QSortFilterProxyModel();
m_filterModel = new QSortFilterProxyModel(this);
m_filterModel->setDynamicSortFilter(true);
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
@ -501,7 +501,7 @@ void VersionPage::on_actionDownload_All_triggered()
return;
}
ProgressDialog tDialog(this);
connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
connect(updateTask.get(), &Task::failed, this, &VersionPage::onGameUpdateError);
// FIXME: unused return value
tDialog.execWithTask(updateTask.get());
updateButtons();

View File

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

View File

@ -41,8 +41,6 @@ class ModPage : public ResourcePage {
return page;
}
~ModPage() override = default;
//: The plural version of 'mod'
[[nodiscard]] inline QString resourcesString() const override { return tr("mods"); }
//: The singular version of 'mods'

View File

@ -9,6 +9,7 @@
#include <QMessageBox>
#include <QPixmapCache>
#include <QUrl>
#include <memory>
#include "Application.h"
#include "BuildConfig.h"
@ -45,16 +46,16 @@ auto ResourceModel::data(const QModelIndex& index, int role) const -> QVariant
auto pack = m_packs.at(pos);
switch (role) {
case Qt::ToolTipRole: {
if (pack.description.length() > 100) {
if (pack->description.length() > 100) {
// some magic to prevent to long tooltips and replace html linebreaks
QString edit = pack.description.left(97);
QString edit = pack->description.left(97);
edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
return edit;
}
return pack.description;
return pack->description;
}
case Qt::DecorationRole: {
if (auto icon_or_none = const_cast<ResourceModel*>(this)->getIcon(const_cast<QModelIndex&>(index), pack.logoUrl);
if (auto icon_or_none = const_cast<ResourceModel*>(this)->getIcon(const_cast<QModelIndex&>(index), pack->logoUrl);
icon_or_none.has_value())
return icon_or_none.value();
@ -64,16 +65,16 @@ auto ResourceModel::data(const QModelIndex& index, int role) const -> QVariant
return QSize(0, 58);
case Qt::UserRole: {
QVariant v;
v.setValue(pack);
v.setValue(*pack);
return v;
}
// Custom data
case UserDataTypes::TITLE:
return pack.name;
return pack->name;
case UserDataTypes::DESCRIPTION:
return pack.description;
return pack->description;
case UserDataTypes::SELECTED:
return pack.isAnyVersionSelected();
return pack->isAnyVersionSelected();
default:
break;
}
@ -102,7 +103,7 @@ bool ResourceModel::setData(const QModelIndex& index, const QVariant& value, int
if (pos >= m_packs.size() || pos < 0 || !index.isValid())
return false;
m_packs[pos] = value.value<ModPlatform::IndexedPack>();
m_packs[pos] = std::make_shared<ModPlatform::IndexedPack>(value.value<ModPlatform::IndexedPack>());
emit dataChanged(index, index);
return true;
@ -161,7 +162,7 @@ void ResourceModel::loadEntry(QModelIndex& entry)
if (!hasActiveInfoJob())
m_current_info_job.clear();
if (!pack.versionsLoaded) {
if (!pack->versionsLoaded) {
auto args{ createVersionsArguments(entry) };
auto callbacks{ createVersionsCallbacks(entry) };
@ -177,7 +178,7 @@ void ResourceModel::loadEntry(QModelIndex& entry)
runInfoJob(job);
}
if (!pack.extraDataLoaded) {
if (!pack->extraDataLoaded) {
auto args{ createInfoArguments(entry) };
auto callbacks{ createInfoCallbacks(entry) };
@ -229,7 +230,7 @@ void ResourceModel::clearData()
void ResourceModel::runSearchJob(Task::Ptr ptr)
{
m_current_search_job = ptr;
m_current_search_job.reset(ptr); // clean up first
m_current_search_job->start();
}
void ResourceModel::runInfoJob(Task::Ptr ptr)
@ -326,15 +327,15 @@ void ResourceModel::loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArra
void ResourceModel::searchRequestSucceeded(QJsonDocument& doc)
{
QList<ModPlatform::IndexedPack> newList;
QList<ModPlatform::IndexedPack::Ptr> newList;
auto packs = documentToArray(doc);
for (auto packRaw : packs) {
auto packObj = packRaw.toObject();
ModPlatform::IndexedPack pack;
ModPlatform::IndexedPack::Ptr pack = std::make_shared<ModPlatform::IndexedPack>();
try {
loadIndexedPack(pack, packObj);
loadIndexedPack(*pack, packObj);
newList.append(pack);
} catch (const JSONValidationError& e) {
qWarning() << "Error while loading resource from " << debugName() << ": " << e.cause();

View File

@ -123,7 +123,7 @@ class ResourceModel : public QAbstractListModel {
QSet<QUrl> m_currently_running_icon_actions;
QSet<QUrl> m_failed_icon_actions;
QList<ModPlatform::IndexedPack> m_packs;
QList<ModPlatform::IndexedPack::Ptr> m_packs;
// HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
// This leaks a tiny bit of memory per time the user has opened a resource dialog. How to make this better?

View File

@ -22,13 +22,13 @@ ResourceAPI::SearchArgs ResourcePackResourceModel::createSearchArguments()
ResourceAPI::VersionSearchArgs ResourcePackResourceModel::createVersionsArguments(QModelIndex& entry)
{
auto& pack = m_packs[entry.row()];
return { pack };
return { *pack };
}
ResourceAPI::ProjectInfoArgs ResourcePackResourceModel::createInfoArguments(QModelIndex& entry)
{
auto& pack = m_packs[entry.row()];
return { pack };
return { *pack };
}
void ResourcePackResourceModel::searchWithTerm(const QString& term, unsigned int sort)

View File

@ -31,8 +31,6 @@ class ResourcePackResourcePage : public ResourcePage {
return page;
}
~ResourcePackResourcePage() override = default;
//: The plural version of 'resource pack'
[[nodiscard]] inline QString resourcesString() const override { return tr("resource packs"); }
//: The singular version of 'resource packs'

View File

@ -83,6 +83,8 @@ ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& base_in
ResourcePage::~ResourcePage()
{
delete m_ui;
if (m_model)
delete m_model;
}
void ResourcePage::retranslate()

View File

@ -22,13 +22,13 @@ ResourceAPI::SearchArgs ShaderPackResourceModel::createSearchArguments()
ResourceAPI::VersionSearchArgs ShaderPackResourceModel::createVersionsArguments(QModelIndex& entry)
{
auto& pack = m_packs[entry.row()];
return { pack };
return { *pack };
}
ResourceAPI::ProjectInfoArgs ShaderPackResourceModel::createInfoArguments(QModelIndex& entry)
{
auto& pack = m_packs[entry.row()];
return { pack };
return { *pack };
}
void ShaderPackResourceModel::searchWithTerm(const QString& term, unsigned int sort)

View File

@ -31,8 +31,6 @@ class ShaderPackResourcePage : public ResourcePage {
return page;
}
~ShaderPackResourcePage() override = default;
//: The plural version of 'shader pack'
[[nodiscard]] inline QString resourcesString() const override { return tr("shader packs"); }
//: The singular version of 'shader packs'