Improve UI

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2024-03-20 00:15:02 +02:00
parent ef4e5eb3cf
commit 09c2c6793b
18 changed files with 295 additions and 296 deletions

View File

@ -0,0 +1,234 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (c) 2024 Trial97 <alexandru.tripon97@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "InstallJavaDialog.h"
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include "Application.h"
#include "FileSystem.h"
#include "java/download/ArchiveDownloadTask.h"
#include "java/download/ManifestDownloadTask.h"
#include "meta/Index.h"
#include "meta/VersionList.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/java/VersionList.h"
#include "ui/widgets/PageContainer.h"
#include "ui/widgets/VersionSelectWidget.h"
class InstallLoaderPage : public QWidget, public BasePage {
public:
Q_OBJECT
public:
explicit InstallLoaderPage(const QString& id, const QString& iconName, const QString& name, QWidget* parent = nullptr)
: QWidget(parent), uid(id), iconName(iconName), name(name)
{
setObjectName(QStringLiteral("VersionSelectWidget"));
horizontalLayout = new QHBoxLayout(this);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
horizontalLayout->setContentsMargins(0, 0, 0, 0);
majorVersionSelect = new VersionSelectWidget(this);
majorVersionSelect->selectCurrent();
majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta."));
majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!"));
horizontalLayout->addWidget(majorVersionSelect, 1);
javaVersionSelect = new VersionSelectWidget(this);
javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS."));
javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!"));
horizontalLayout->addWidget(javaVersionSelect, 4);
connect(majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::setSelectedVersion);
connect(javaVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &InstallLoaderPage::selectedVersionChanged);
QMetaObject::connectSlotsByName(this);
}
~InstallLoaderPage()
{
delete horizontalLayout;
delete majorVersionSelect;
delete javaVersionSelect;
}
//! loads the list if needed.
void initialize(Meta::VersionList::Ptr vlist)
{
vlist->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole });
majorVersionSelect->initialize(vlist.get());
}
void setSelectedVersion(BaseVersion::Ptr version)
{
auto dcast = std::dynamic_pointer_cast<Meta::Version>(version);
if (!dcast) {
return;
}
javaVersionSelect->initialize(new Java::VersionList(dcast, this));
javaVersionSelect->selectCurrent();
}
QString id() const override { return uid; }
QString displayName() const override { return name; }
QIcon icon() const override { return APPLICATION->getThemedIcon(iconName); }
void openedImpl() override
{
if (loaded)
return;
const auto versions = APPLICATION->metadataIndex()->get(uid);
if (!versions)
return;
initialize(versions);
loaded = true;
}
void setParentContainer(BasePageContainer* container) override
{
auto dialog = dynamic_cast<QDialog*>(dynamic_cast<PageContainer*>(container)->parent());
connect(javaVersionSelect->view(), &QAbstractItemView::doubleClicked, dialog, &QDialog::accept);
}
BaseVersion::Ptr selectedVersion() const { return javaVersionSelect->selectedVersion(); }
void selectSearch() { javaVersionSelect->selectSearch(); }
void loadList()
{
majorVersionSelect->loadList();
javaVersionSelect->loadList();
}
signals:
void selectedVersionChanged(BaseVersion::Ptr version);
private:
const QString uid;
const QString iconName;
const QString name;
bool loaded = false;
QHBoxLayout* horizontalLayout = nullptr;
VersionSelectWidget* majorVersionSelect = nullptr;
VersionSelectWidget* javaVersionSelect = nullptr;
};
static InstallLoaderPage* pageCast(BasePage* page)
{
auto result = dynamic_cast<InstallLoaderPage*>(page);
Q_ASSERT(result != nullptr);
return result;
}
namespace Java {
InstallDialog::InstallDialog(const QString& uid, QWidget* parent)
: QDialog(parent), container(new PageContainer(this, QString(), this)), buttons(new QDialogButtonBox(this))
{
auto layout = new QVBoxLayout(this);
container->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
layout->addWidget(container);
auto buttonLayout = new QHBoxLayout(this);
auto refreshButton = new QPushButton(tr("&Refresh"), this);
connect(refreshButton, &QPushButton::clicked, this, [this] { pageCast(container->selectedPage())->loadList(); });
buttonLayout->addWidget(refreshButton);
buttons->setOrientation(Qt::Horizontal);
buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
buttons->button(QDialogButtonBox::Ok)->setText(tr("Download"));
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
buttonLayout->addWidget(buttons);
layout->addLayout(buttonLayout);
setWindowTitle(dialogTitle());
setWindowModality(Qt::WindowModal);
resize(840, 480);
for (BasePage* page : container->getPages()) {
if (page->id() == uid)
container->selectPage(page->id());
connect(pageCast(page), &InstallLoaderPage::selectedVersionChanged, this, [this, page] {
if (page->id() == container->selectedPage()->id())
validate(container->selectedPage());
});
}
connect(container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* current) { validate(current); });
pageCast(container->selectedPage())->selectSearch();
validate(container->selectedPage());
}
QList<BasePage*> InstallDialog::getPages()
{
return {
// NeoForge
new InstallLoaderPage("net.minecraft.java", "", tr("Mojang")),
// Forge
new InstallLoaderPage("net.adoptium.java", "", tr("Adoptium")),
// Fabric
new InstallLoaderPage("com.azul.java", "", tr("Azul")),
};
}
QString InstallDialog::dialogTitle()
{
return tr("Install Loader");
}
void InstallDialog::validate(BasePage* page)
{
buttons->button(QDialogButtonBox::Ok)->setEnabled(pageCast(page)->selectedVersion() != nullptr);
}
void InstallDialog::done(int result)
{
if (result == Accepted) {
auto* page = pageCast(container->selectedPage());
if (page->selectedVersion()) {
auto meta = std::dynamic_pointer_cast<Java::Metadata>(page->selectedVersion());
if (meta) {
Task::Ptr task;
auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name);
switch (meta->downloadType) {
case Java::DownloadType::Manifest:
task = makeShared<ManifestDownloadTask>(meta->url, final_path, meta->checksumType, meta->checksumHash);
break;
case Java::DownloadType::Archive:
task = makeShared<ArchiveDownloadTask>(meta->url, final_path, meta->checksumType, meta->checksumHash);
break;
}
auto deletePath = [final_path] { FS::deletePath(final_path); };
connect(task.get(), &Task::failed, this, deletePath);
connect(task.get(), &Task::aborted, this, deletePath);
ProgressDialog pg(this);
pg.setSkipButton(true, tr("Abort"));
pg.execWithTask(task.get());
}
}
}
QDialog::done(result);
}
} // namespace Java
#include "InstallJavaDialog.moc"

View File

@ -19,30 +19,28 @@
#pragma once
#include <QDialog>
#include "BaseVersion.h"
#include "ui/pages/BasePageProvider.h"
namespace Ui {
class JavaDownloader;
}
class MinecraftInstance;
class PageContainer;
class PackProfile;
class QDialogButtonBox;
namespace Java {
class Downloader : public QDialog {
class InstallDialog final : public QDialog, protected BasePageProvider {
Q_OBJECT
public:
explicit Downloader(QWidget* parent = 0);
~Downloader();
explicit InstallDialog(const QString& uid = QString(), QWidget* parent = nullptr);
void accept();
QList<BasePage*> getPages() override;
QString dialogTitle() override;
public slots:
void refresh();
protected slots:
void setSelectedVersion(BaseVersion::Ptr version);
void validate(BasePage* page);
void done(int result) override;
private:
Ui::JavaDownloader* ui;
PageContainer* container;
QDialogButtonBox* buttons;
};
} // namespace Java

View File

@ -1,110 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (c) 2024 Trial97 <alexandru.tripon97@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "JavaDownloader.h"
#include <QPushButton>
#include <memory>
#include "Application.h"
#include "BaseVersionList.h"
#include "FileSystem.h"
#include "QObjectPtr.h"
#include "SysInfo.h"
#include "java/JavaMetadata.h"
#include "java/download/ArchiveDownloadTask.h"
#include "java/download/ManifestDownloadTask.h"
#include "meta/Index.h"
#include "meta/Version.h"
#include "meta/VersionList.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/java/VersionList.h"
#include "ui_JavaDownloader.h"
namespace Java {
Downloader::Downloader(QWidget* parent) : QDialog(parent), ui(new Ui::JavaDownloader)
{
ui->setupUi(this);
auto versionList = APPLICATION->metadataIndex()->get("net.minecraft.java");
versionList->setProvidedRoles({ BaseVersionList::VersionRole, BaseVersionList::RecommendedRole, BaseVersionList::VersionPointerRole });
ui->majorVersionSelect->initialize(versionList.get());
ui->majorVersionSelect->selectCurrent();
ui->majorVersionSelect->setEmptyString(tr("No java versions are currently available in the meta."));
ui->majorVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!"));
ui->javaVersionSelect->setEmptyString(tr("No java versions are currently available for your OS."));
ui->javaVersionSelect->setEmptyErrorString(tr("Couldn't load or download the java version lists!"));
ui->buttonBox->button(QDialogButtonBox::Reset)->setText(tr("Refresh"));
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Download"));
connect(ui->majorVersionSelect, &VersionSelectWidget::selectedVersionChanged, this, &Downloader::setSelectedVersion);
auto reset = ui->buttonBox->button(QDialogButtonBox::Reset);
connect(reset, &QPushButton::clicked, this, &Downloader::refresh);
}
Downloader::~Downloader()
{
delete ui;
}
void Downloader::setSelectedVersion(BaseVersion::Ptr version)
{
auto dcast = std::dynamic_pointer_cast<Meta::Version>(version);
if (!dcast) {
return;
}
ui->javaVersionSelect->initialize(new Java::VersionList(dcast, this));
ui->javaVersionSelect->selectCurrent();
}
void Downloader::accept()
{
auto meta = std::dynamic_pointer_cast<Java::Metadata>(ui->javaVersionSelect->selectedVersion());
if (!meta) {
return;
}
Task::Ptr task;
auto final_path = FS::PathCombine(APPLICATION->javaPath(), meta->m_name);
switch (meta->downloadType) {
case Java::DownloadType::Manifest:
task = makeShared<ManifestDownloadTask>(meta->url, final_path, meta->checksumType, meta->checksumHash);
break;
case Java::DownloadType::Archive:
task = makeShared<ArchiveDownloadTask>(meta->url, final_path, meta->checksumType, meta->checksumHash);
break;
}
auto deletePath = [final_path] { FS::deletePath(final_path); };
connect(task.get(), &Task::failed, this, deletePath);
connect(task.get(), &Task::aborted, this, deletePath);
ProgressDialog pg(this);
pg.setSkipButton(true, tr("Abort"));
pg.execWithTask(task.get());
QDialog::accept();
}
void Downloader::refresh()
{
ui->majorVersionSelect->loadList();
}
} // namespace Java

View File

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>JavaDownloader</class>
<widget class="QDialog" name="JavaDownloader">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>821</width>
<height>593</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,5">
<item>
<widget class="QGroupBox" name="majorGB">
<property name="title">
<string>Major</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="VersionSelectWidget" name="majorVersionSelect" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="runtimeGB">
<property name="title">
<string>Runtime</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="VersionSelectWidget" name="javaVersionSelect" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>VersionSelectWidget</class>
<extends>QWidget</extends>
<header>ui/widgets/VersionSelectWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>JavaDownloader</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>583</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>JavaDownloader</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>583</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -75,11 +75,9 @@ QVariant VersionList::data(const QModelIndex& index, int role) const
case VersionRole:
return version->version.toString();
case RecommendedRole:
return version->recommended;
return false; // do not recommend any version
case JavaNameRole:
return version->name();
case JavaVendorRole:
return version->vendor;
case TypeRole:
return version->packageType;
case Meta::VersionList::TimeRole:
@ -91,8 +89,7 @@ QVariant VersionList::data(const QModelIndex& index, int role) const
BaseVersionList::RoleList VersionList::providesRoles() const
{
return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole,
JavaNameRole, JavaVendorRole, TypeRole, Meta::VersionList::TimeRole };
return { VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, JavaNameRole, TypeRole, Meta::VersionList::TimeRole };
}
bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right)
@ -109,11 +106,12 @@ void VersionList::sortVersions()
QString versionStr = SysInfo::getSupportedJavaArchitecture();
beginResetModel();
auto runtimes = m_version->data()->runtimes;
if (!versionStr.isEmpty() && !runtimes.isEmpty() && runtimes.contains(versionStr)) {
m_vlist = runtimes.value(versionStr);
m_vlist = {};
if (!versionStr.isEmpty() && !runtimes.isEmpty()) {
std::copy_if(runtimes.begin(), runtimes.end(), std::back_inserter(m_vlist),
[versionStr](Java::MetadataPtr val) { return val->runtimeOS == versionStr; });
std::sort(m_vlist.begin(), m_vlist.end(), sortJavas);
} else {
m_vlist = {};
qWarning() << "No Java versions found for your operating system." << SysInfo::currentSystem() << " " << SysInfo::useQTForArch();
}
endResetModel();

View File

@ -39,7 +39,7 @@
#include "JavaCommon.h"
#include "java/JavaInstall.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/java/JavaDownloader.h"
#include "ui/java/InstallJavaDialog.h"
#include "ui_JavaPage.h"
#include <QCheckBox>
@ -201,7 +201,7 @@ void JavaPage::on_javaTestBtn_clicked()
void JavaPage::on_javaDownloadBtn_clicked()
{
auto jdialog = new Java::Downloader(this);
auto jdialog = new Java::InstallDialog({}, this);
jdialog->exec();
ui->managedJavaList->loadList();
}

View File

@ -37,7 +37,7 @@
#include "InstanceSettingsPage.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/java/JavaDownloader.h"
#include "ui/java/InstallJavaDialog.h"
#include "ui_InstanceSettingsPage.h"
#include <QDialog>
@ -394,7 +394,7 @@ void InstanceSettingsPage::loadSettings()
void InstanceSettingsPage::on_javaDownloadBtn_clicked()
{
auto jdialog = new Java::Downloader(this);
auto jdialog = new Java::InstallDialog({}, this);
jdialog->exec();
}

View File

@ -21,7 +21,7 @@
#include "java/JavaUtils.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/java/JavaDownloader.h"
#include "ui/java/InstallJavaDialog.h"
#include "ui/widgets/VersionSelectWidget.h"
#include "Application.h"
@ -351,7 +351,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked()
void JavaSettingsWidget::on_javaDownloadBtn_clicked()
{
auto jdialog = new Java::Downloader(this);
auto jdialog = new Java::InstallDialog({}, this);
jdialog->exec();
}