From 7dd159aac086b07cbe434d5bd3a8918708a47327 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 21 Mar 2025 01:39:30 +0000 Subject: [PATCH 01/62] Rework Launcher as General category Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.cpp | 98 +- launcher/ui/pages/global/LauncherPage.h | 21 +- launcher/ui/pages/global/LauncherPage.ui | 1088 ++++++++++----------- 3 files changed, 511 insertions(+), 696 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 04ee01b00..36d404660 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -72,24 +72,14 @@ LauncherPage::LauncherPage(QWidget* parent) : QWidget(parent), ui(new Ui::Launch ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); - defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); - - m_languageModel = APPLICATION->translations(); loadSettings(); ui->updateSettingsBox->setHidden(!APPLICATION->updater()); - - connect(ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &LauncherPage::refreshFontPreview); - connect(ui->consoleFont, &QFontComboBox::currentFontChanged, this, &LauncherPage::refreshFontPreview); - connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentWidgetThemeChanged, this, &LauncherPage::refreshFontPreview); - - connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, APPLICATION, &Application::currentCatChanged); } LauncherPage::~LauncherPage() { delete ui; - delete defaultFormat; } bool LauncherPage::apply() @@ -194,9 +184,9 @@ void LauncherPage::on_skinsDirBrowseBtn_clicked() } } -void LauncherPage::on_metadataDisableBtn_clicked() +void LauncherPage::on_metadataEnableBtn_clicked() { - ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked()); + ui->metadataWarningLabel->setHidden(ui->metadataEnableBtn->isChecked()); } void LauncherPage::applySettings() @@ -217,9 +207,6 @@ void LauncherPage::applySettings() s->set("RequestTimeout", ui->timeoutSecondsSpinBox->value()); // Console settings - QString consoleFontFamily = ui->consoleFont->currentFont().family(); - s->set("ConsoleFont", consoleFontFamily); - s->set("ConsoleFontSize", ui->fontSizeBox->value()); s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value()); s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked); @@ -245,13 +232,10 @@ void LauncherPage::applySettings() break; } - // Cat - s->set("CatOpacity", ui->catOpacitySpinBox->value()); - // Mods - s->set("ModMetadataDisabled", ui->metadataDisableBtn->isChecked()); - s->set("ModDependenciesDisabled", ui->dependenciesDisableBtn->isChecked()); - s->set("SkipModpackUpdatePrompt", ui->skipModpackUpdatePromptBtn->isChecked()); + s->set("ModMetadataDisabled", !ui->metadataEnableBtn->isChecked()); + s->set("ModDependenciesDisabled", !ui->dependenciesEnableBtn->isChecked()); + s->set("SkipModpackUpdatePrompt", !ui->modpackUpdatePromptBtn->isChecked()); } void LauncherPage::loadSettings() { @@ -262,11 +246,6 @@ void LauncherPage::loadSettings() ui->updateIntervalSpinBox->setValue(APPLICATION->updater()->getUpdateCheckInterval() / 3600); } - // Toolbar/menu bar settings (not applicable if native menu bar is present) - ui->toolsBox->setEnabled(!QMenuBar().isNativeMenuBar()); -#ifdef Q_OS_MACOS - ui->toolsBox->setVisible(!QMenuBar().isNativeMenuBar()); -#endif ui->preferMenuBarCheckBox->setChecked(s->get("MenuBarInsteadOfToolBar").toBool()); ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt()); @@ -275,17 +254,6 @@ void LauncherPage::loadSettings() ui->timeoutSecondsSpinBox->setValue(s->get("RequestTimeout").toInt()); // Console settings - QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); - QFont consoleFont(fontFamily); - ui->consoleFont->setCurrentFont(consoleFont); - - bool conversionOk = true; - int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); - if (!conversionOk) { - fontSize = 11; - } - ui->fontSizeBox->setValue(fontSize); - refreshFontPreview(); ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt()); ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool()); @@ -307,59 +275,11 @@ void LauncherPage::loadSettings() ui->sortByNameBtn->setChecked(true); } - // Cat - ui->catOpacitySpinBox->setValue(s->get("CatOpacity").toInt()); - // Mods - ui->metadataDisableBtn->setChecked(s->get("ModMetadataDisabled").toBool()); - ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked()); - ui->dependenciesDisableBtn->setChecked(s->get("ModDependenciesDisabled").toBool()); - ui->skipModpackUpdatePromptBtn->setChecked(s->get("SkipModpackUpdatePrompt").toBool()); -} - -void LauncherPage::refreshFontPreview() -{ - const LogColors& colors = APPLICATION->themeManager()->getLogColors(); - - int fontSize = ui->fontSizeBox->value(); - QString fontFamily = ui->consoleFont->currentFont().family(); - ui->fontPreview->clear(); - defaultFormat->setFont(QFont(fontFamily, fontSize)); - - auto print = [this, colors](const QString& message, MessageLevel::Enum level) { - QTextCharFormat format(*defaultFormat); - - QColor bg = colors.background.value(level); - QColor fg = colors.foreground.value(level); - - if (bg.isValid()) - format.setBackground(bg); - - if (fg.isValid()) - format.setForeground(fg); - - // append a paragraph/line - auto workCursor = ui->fontPreview->textCursor(); - workCursor.movePosition(QTextCursor::End); - workCursor.insertText(message, format); - workCursor.insertBlock(); - }; - - print(QString("%1 version: %2 (%3)\n") - .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM), - MessageLevel::Launcher); - - QDate today = QDate::currentDate(); - - if (today.month() == 10 && today.day() == 31) - print(tr("[Test/ERROR] OOoooOOOoooo! A spooky error!"), MessageLevel::Error); - else - print(tr("[Test/ERROR] A spooky error!"), MessageLevel::Error); - - print(tr("[Test/INFO] A harmless message..."), MessageLevel::Info); - print(tr("[Test/WARN] A not so spooky warning."), MessageLevel::Warning); - print(tr("[Test/DEBUG] A secret debugging message..."), MessageLevel::Debug); - print(tr("[Test/FATAL] A terrifying fatal error!"), MessageLevel::Fatal); + ui->metadataEnableBtn->setChecked(!s->get("ModMetadataDisabled").toBool()); + ui->metadataWarningLabel->setHidden(ui->metadataEnableBtn->isChecked()); + ui->dependenciesEnableBtn->setChecked(!s->get("ModDependenciesDisabled").toBool()); + ui->modpackUpdatePromptBtn->setChecked(!s->get("SkipModpackUpdatePrompt").toBool()); } void LauncherPage::retranslate() diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index 02f371b04..d76c84b63 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -57,8 +57,8 @@ class LauncherPage : public QWidget, public BasePage { explicit LauncherPage(QWidget* parent = 0); ~LauncherPage(); - QString displayName() const override { return tr("Launcher"); } - QIcon icon() const override { return APPLICATION->getThemedIcon("launcher"); } + QString displayName() const override { return tr("General"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("settings"); } QString id() const override { return "launcher-settings"; } QString helpPage() const override { return "Launcher-settings"; } bool apply() override; @@ -75,23 +75,8 @@ class LauncherPage : public QWidget, public BasePage { void on_downloadsDirBrowseBtn_clicked(); void on_javaDirBrowseBtn_clicked(); void on_skinsDirBrowseBtn_clicked(); - void on_metadataDisableBtn_clicked(); - - /*! - * Updates the font preview - */ - void refreshFontPreview(); + void on_metadataEnableBtn_clicked(); private: Ui::LauncherPage* ui; - - /*! - * Stores the currently selected update channel. - */ - QString m_currentUpdateChannel; - - // default format for the font preview... - QTextCharFormat* defaultFormat; - - std::shared_ptr m_languageModel; }; diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 31c878f3e..f4d329c44 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -6,8 +6,8 @@ 0 0 - 511 - 726 + 600 + 700 @@ -16,407 +16,39 @@ 0 - - - 0 - - - 0 - - - 0 - - - 0 - + - - - + + + Qt::ScrollBarAsNeeded - - QTabWidget::Rounded + + true - - 0 - - - - Features - - + + + + 0 + 0 + 563 + 1293 + + + - - - Qt::ScrollBarAsNeeded - - - true - - - - - 0 - 0 - 473 - 770 - - - - - - - Update Settings - - - - - - Check for updates automatically - - - - - - - - - Update interval - - - - - - - Set it to 0 to only check on launch - - - h - - - 0 - - - 99999999 - - - - - - - - - - - - Folders - - - - - - &Downloads: - - - downloadsDirTextBox - - - - - - - Browse - - - - - - - - - - - - - &Skins: - - - skinsDirTextBox - - - - - - - &Icons: - - - iconsDirTextBox - - - - - - - - - When enabled, in addition to the downloads folder, its sub folders will also be searched when looking for resources (e.g. when looking for blocked mods on CurseForge). - - - Check downloads folder recursively - - - - - - - When enabled, it will move blocked resources instead of copying them. - - - Move blocked resources - - - - - - - - - - - - &Java: - - - javaDirTextBox - - - - - - - &Mods: - - - modsDirTextBox - - - - - - - - - - - - - - - - Browse - - - - - - - Browse - - - - - - - Browse - - - - - - - I&nstances: - - - instDirTextBox - - - - - - - Browse - - - - - - - Browse - - - - - - - - - - Mods - - - - - - Disable using metadata provided by mod providers (like Modrinth or CurseForge) for mods. - - - Disable using metadata for mods - - - - - - - <html><head/><body><p><span style=" font-weight:600; color:#f5c211;">Warning</span><span style=" color:#f5c211;">: Disabling mod metadata may also disable some QoL features, such as mod updating!</span></p></body></html> - - - true - - - - - - - Disable the automatic detection, installation, and updating of mod dependencies. - - - Disable automatic mod dependency management - - - - - - - When creating a new modpack instance, do not suggest updating existing instances instead. - - - Skip modpack update prompt - - - - - - - - - - Miscellaneous - - - - - - 1 - - - - - - - Number of concurrent tasks - - - - - - - 1 - - - - - - - Number of concurrent downloads - - - - - - - Number of manual retries - - - - - - - 0 - - - - - - - Seconds to wait until the requests are terminated - - - Timeout for HTTP requests - - - - - - - s - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - - User Interface - - - - + true - Instance view sorting mode + User Interface - + - + - &By last launched + Instance Sorting - - sortingModeGroup - @@ -429,81 +61,23 @@ - - - - - - - Theme - - - - - - - - - - - Cat - - - - - - Set the cat's opacity. 0% is fully transparent and 100% is fully opaque. - + - Opacity + &By last launched + + sortingModeGroup + - - - - - - - % - - - 100 - - - 0 - - - - - + + Qt::Horizontal - - - 40 - 20 - - - + - - - - - - - - 0 - 0 - - - - Tools - - @@ -518,7 +92,471 @@ - + + + Updater + + + + + + Check for updates automatically + + + + + + + Update checking interval + + + + + + + + + Set it to 0 to only check on launch + + + h + + + 0 + + + 168 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + + Folders + + + + + + &Downloads + + + downloadsDirTextBox + + + + + + + Browse + + + + + + + + + + + + + &Skins + + + skinsDirTextBox + + + + + + + &Icons + + + iconsDirTextBox + + + + + + + + + + + + + &Java + + + javaDirTextBox + + + + + + + &Mods + + + modsDirTextBox + + + + + + + + + + + + + + + + Browse + + + + + + + Browse + + + + + + + Browse + + + + + + + I&nstances + + + instDirTextBox + + + + + + + Browse + + + + + + + Browse + + + + + + + + + + Mod Management + + + + + + When enabled, in addition to the downloads folder, its sub folders will also be searched when looking for resources (e.g. when looking for blocked mods on CurseForge). + + + Check &subfolders for blocked mods + + + + + + + When enabled, it will move blocked resources instead of copying them. + + + Move blocked mods instead of copying them + + + + + + + Disable using metadata provided by mod providers (like Modrinth or CurseForge) for mods. + + + Keep track of mod metadata + + + + + + + <html><head/><body><p><span style=" font-weight:600; color:#f5c211;">Warning</span><span style=" color:#f5c211;">: Disabling mod metadata may also disable some QoL features, such as mod updating!</span></p></body></html> + + + true + + + + + + + Disable the automatic detection, installation, and updating of mod dependencies. + + + Install dependencies automatically + + + + + + + + + + Modpacks + + + + + + When creating a new modpack instance, do not suggest updating existing instances instead. + + + Ask whether to update an existing instance when installing modpacks + + + + + + + + + + Console + + + + + + Log History &Limit + + + lineLimitSpinBox + + + + + + + + + + 0 + 0 + + + + lines + + + 10000 + + + 1000000 + + + 10000 + + + 100000 + + + + + + + Qt::Horizontal + + + + + + + + + &Stop logging when log overflows + + + + + + + + + + Tasks + + + + + + Number of concurrent tasks + + + + + + + + + 1 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + Number of concurrent downloads + + + + + + + + + 1 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + Number of manual retries + + + + + + + + + 0 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + Seconds to wait until the requests are terminated + + + Timeout for HTTP requests + + + + + + + + + s + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical @@ -532,128 +570,13 @@ - - - Console - - - - - - &History limit - - - - - - &Stop logging when log overflows - - - - - - - - 0 - 0 - - - - lines - - - 10000 - - - 1000000 - - - 10000 - - - 100000 - - - - - - - - - - - 0 - 0 - - - - Console &font - - - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - false - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - - - - - 5 - - - 16 - - - 11 - - - - - - - - - - - ThemeCustomizationWidget - QWidget -
ui/widgets/ThemeCustomizationWidget.h
- 1 -
-
- tabWidget scrollArea autoUpdateCheckBox - updateIntervalSpinBox instDirTextBox instDirBrowseBtn modsDirTextBox @@ -666,27 +589,14 @@ skinsDirBrowseBtn downloadsDirTextBox downloadsDirBrowseBtn - downloadsDirWatchRecursiveCheckBox - metadataDisableBtn - dependenciesDisableBtn - skipModpackUpdatePromptBtn - numberOfConcurrentTasksSpinBox - numberOfConcurrentDownloadsSpinBox - numberOfManualRetriesSpinBox - timeoutSecondsSpinBox + metadataEnableBtn + dependenciesEnableBtn sortLastLaunchedBtn sortByNameBtn - catOpacitySpinBox - preferMenuBarCheckBox - lineLimitSpinBox - checkStopLogging - consoleFont - fontSizeBox - fontPreview - \ No newline at end of file + From dced39cab06ad6e4726adf0ce1dc539a94ea3e83 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 21 Mar 2025 11:04:05 +0000 Subject: [PATCH 02/62] Add appearance page Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 + launcher/CMakeLists.txt | 5 +- launcher/ui/pages/global/AppearancePage.cpp | 104 +++++++ launcher/ui/pages/global/AppearancePage.h | 75 +++++ launcher/ui/pages/global/AppearancePage.ui | 286 ++++++++++++++++++ .../ui/widgets/ThemeCustomizationWidget.ui | 277 +++++++---------- 6 files changed, 579 insertions(+), 170 deletions(-) create mode 100644 launcher/ui/pages/global/AppearancePage.cpp create mode 100644 launcher/ui/pages/global/AppearancePage.h create mode 100644 launcher/ui/pages/global/AppearancePage.ui diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c3477d331..b1cad5ad4 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -137,6 +137,7 @@ #if defined(Q_OS_LINUX) #include +#include #endif #if defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) @@ -798,6 +799,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) { m_globalSettingsProvider = std::make_shared(tr("Settings")); m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 0e4204cfb..0c07ca618 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -924,7 +924,7 @@ SET(LAUNCHER_SOURCES ui/pages/instance/McResolver.h ui/pages/instance/ServerPingTask.cpp ui/pages/instance/ServerPingTask.h - + # GUI - global settings pages ui/pages/global/AccountListPage.cpp ui/pages/global/AccountListPage.h @@ -937,6 +937,8 @@ SET(LAUNCHER_SOURCES ui/pages/global/MinecraftPage.h ui/pages/global/LauncherPage.cpp ui/pages/global/LauncherPage.h + ui/pages/global/AppearancePage.cpp + ui/pages/global/AppearancePage.h ui/pages/global/ProxyPage.cpp ui/pages/global/ProxyPage.h ui/pages/global/APIPage.cpp @@ -1177,6 +1179,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/global/AccountListPage.ui ui/pages/global/JavaPage.ui ui/pages/global/LauncherPage.ui + ui/pages/global/AppearancePage.ui ui/pages/global/APIPage.ui ui/pages/global/ProxyPage.ui ui/pages/global/ExternalToolsPage.ui diff --git a/launcher/ui/pages/global/AppearancePage.cpp b/launcher/ui/pages/global/AppearancePage.cpp new file mode 100644 index 000000000..7b6c893c7 --- /dev/null +++ b/launcher/ui/pages/global/AppearancePage.cpp @@ -0,0 +1,104 @@ +#include "AppearancePage.h" +#include "ui_AppearancePage.h" + +#include +#include +#include + +AppearancePage::AppearancePage(QWidget* parent) : QWidget(parent), m_ui(new Ui::AppearancePage) +{ + m_ui->setupUi(this); + + defaultFormat = new QTextCharFormat(m_ui->fontPreview->currentCharFormat()); + + loadSettings(); + connect(m_ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearancePage::updateFontPreview); + connect(m_ui->consoleFont, &QFontComboBox::currentFontChanged, this, &AppearancePage::updateFontPreview); + connect(m_ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentWidgetThemeChanged, this, &AppearancePage::updateFontPreview); + connect(m_ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, APPLICATION, &Application::currentCatChanged); +} + +AppearancePage::~AppearancePage() +{ + delete m_ui; +} + +bool AppearancePage::apply() +{ + applySettings(); + return true; +} + +void AppearancePage::retranslate() +{ + m_ui->retranslateUi(this); +} + +void AppearancePage::applySettings() +{ + SettingsObjectPtr settings = APPLICATION->settings(); + QString consoleFontFamily = m_ui->consoleFont->currentFont().family(); + settings->set("ConsoleFont", consoleFontFamily); + settings->set("ConsoleFontSize", m_ui->fontSizeBox->value()); +} + +void AppearancePage::loadSettings() +{ + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); + QFont consoleFont(fontFamily); + m_ui->consoleFont->setCurrentFont(consoleFont); + + bool conversionOk = true; + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); + if (!conversionOk) { + fontSize = 11; + } + m_ui->fontSizeBox->setValue(fontSize); + + updateFontPreview(); +} + +void AppearancePage::updateFontPreview() +{ + const LogColors& colors = APPLICATION->themeManager()->getLogColors(); + + int fontSize = m_ui->fontSizeBox->value(); + QString fontFamily = m_ui->consoleFont->currentFont().family(); + m_ui->fontPreview->clear(); + defaultFormat->setFont(QFont(fontFamily, fontSize)); + + auto print = [this, colors](const QString& message, MessageLevel::Enum level) { + QTextCharFormat format(*defaultFormat); + + QColor bg = colors.background.value(level); + QColor fg = colors.foreground.value(level); + + if (bg.isValid()) + format.setBackground(bg); + + if (fg.isValid()) + format.setForeground(fg); + + // append a paragraph/line + auto workCursor = m_ui->fontPreview->textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(message, format); + workCursor.insertBlock(); + }; + + print(QString("%1 version: %2 (%3)\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM), + MessageLevel::Launcher); + + QDate today = QDate::currentDate(); + + if (today.month() == 10 && today.day() == 31) + print(tr("[Test/ERROR] OOoooOOOoooo! A spooky error!"), MessageLevel::Error); + else + print(tr("[Test/ERROR] A spooky error!"), MessageLevel::Error); + + print(tr("[Test/INFO] A harmless message..."), MessageLevel::Info); + print(tr("[Test/WARN] A not so spooky warning."), MessageLevel::Warning); + print(tr("[Test/DEBUG] A secret debugging message..."), MessageLevel::Debug); + print(tr("[Test/FATAL] A terrifying fatal error!"), MessageLevel::Fatal); +} diff --git a/launcher/ui/pages/global/AppearancePage.h b/launcher/ui/pages/global/AppearancePage.h new file mode 100644 index 000000000..fe7cb3da7 --- /dev/null +++ b/launcher/ui/pages/global/AppearancePage.h @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include +#include +#include "java/JavaChecker.h" +#include "ui/pages/BasePage.h" + +class QTextCharFormat; +class SettingsObject; + +namespace Ui { +class AppearancePage; +} + +class AppearancePage : public QWidget, public BasePage { + Q_OBJECT + + public: + explicit AppearancePage(QWidget* parent = 0); + ~AppearancePage(); + + QString displayName() const override { return tr("Appearance"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); } + QString id() const override { return "appearance-settings"; } + QString helpPage() const override { return "Launcher-settings"; } + bool apply() override; + void retranslate() override; + + private: + void applySettings(); + void loadSettings(); + void updateFontPreview(); + + private: + Ui::AppearancePage* m_ui; + QTextCharFormat* defaultFormat; +}; diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/pages/global/AppearancePage.ui new file mode 100644 index 000000000..d3ddfdb20 --- /dev/null +++ b/launcher/ui/pages/global/AppearancePage.ui @@ -0,0 +1,286 @@ + + + AppearancePage + + + + 0 + 0 + 600 + 700 + + + + Form + + + + + + Theme + + + + + + + + + + + + + 0 + 0 + + + + &Fonts + + + + + + + 0 + 0 + + + + + + + + 5 + + + 16 + + + 11 + + + + + + + Monospace Font + + + + + + + + + + Preview + + + + + + Icons + + + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + + + + + .. + + + true + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + + + + Console + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAsNeeded + + + false + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + ThemeCustomizationWidget + QWidget +
ui/widgets/ThemeCustomizationWidget.h
+ 1 +
+
+ + +
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui index 1faa45c4f..ed05c4292 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.ui +++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui @@ -13,180 +13,125 @@ Form - - - QLayout::SetMinimumSize - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - &Icons - - - iconsComboBox - - - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - View icon themes folder. - - - - - - - - - true - - - - - - - - - &Widgets - - - widgetStyleComboBox - - - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - View widget themes folder. - - - - - - - - - true - - - - - - - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - C&at - - - backgroundCatComboBox - - - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - - - - - View cat packs folder. - - - - - - - - - true - - - - - - + + + + + View icon themes folder. + + + Open Folder + + - - + + + + The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. + + + C&at + + + backgroundCatComboBox + + + + + + + View cat packs folder. + + + Open Folder + + + + + + + &Icons + + + iconsComboBox + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + &Widgets + + + widgetStyleComboBox + + + + + + + View widget themes folder. + + + Open Folder + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + Qt::Horizontal - - - 40 - 20 - - - Refresh all + Refresh All @@ -195,12 +140,6 @@ Qt::Horizontal - - - 40 - 20 - - From 414ad1340d716b60ddbab077ca8f0c2414efd5bc Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 21 Mar 2025 15:30:05 +0000 Subject: [PATCH 03/62] Rework API page design and rename to services Signed-off-by: TheKodeToad --- launcher/ui/pages/global/APIPage.h | 2 +- launcher/ui/pages/global/APIPage.ui | 488 +++++++++++++--------------- 2 files changed, 232 insertions(+), 258 deletions(-) diff --git a/launcher/ui/pages/global/APIPage.h b/launcher/ui/pages/global/APIPage.h index d4ed92900..9252a9ab3 100644 --- a/launcher/ui/pages/global/APIPage.h +++ b/launcher/ui/pages/global/APIPage.h @@ -53,7 +53,7 @@ class APIPage : public QWidget, public BasePage { explicit APIPage(QWidget* parent = 0); ~APIPage(); - QString displayName() const override { return tr("APIs"); } + QString displayName() const override { return tr("Services"); } QIcon icon() const override { return APPLICATION->getThemedIcon("worlds"); } QString id() const override { return "apis"; } QString helpPage() const override { return "APIs"; } diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 05c256bb2..ab4bdf83e 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -10,29 +10,50 @@ 620 - - - 0 - - - 0 - - - 0 - - - 0 - + - - - 0 + + + true - - - Services - - + + + + 0 + -342 + 804 + 946 + + + + + + + + 0 + 0 + + + + User Agent + + + + + + + + + Enter a custom User Agent here. The special string $LAUNCHER_VER will be replaced with the version of the launcher. + + + true + + + + + + @@ -92,9 +113,9 @@ - + - You can set this to a third-party metadata server to use patched libraries or other hacks. + Base URL Qt::RichText @@ -114,7 +135,7 @@ - Enter a custom URL for meta here. + You can set this to a third-party metadata server to use patched libraries or other hacks. Qt::RichText @@ -130,250 +151,203 @@ + + + + &Microsoft Authentication + + + + + + &Client ID + + + Qt::RichText + + + true + + + true + + + msaClientID + + + + + + + (Default) + + + + + + + Note: you probably don't need to set this if logging in via Microsoft Authentication already works. + + + Qt::RichText + + + true + + + + + + + + + + true + + + &Modrinth + + + + + + true + + + (None) + + + + + + + &API Token + + + Qt::RichText + + + true + + + true + + + modrinthToken + + + + + + + <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/api/#authentication">documentation</a> for more information.</p></body></html> + + + true + + + true + + + + + + + + + + true + + + &CurseForge + + + + + + true + + + (Default) + + + + + + + API &Key + + + Qt::RichText + + + true + + + true + + + flameKey + + + + + + + Note: you probably don't need to set this if CurseForge already works. + + + true + + + + + + + + + + Technic + + + + + + GUID Client ID + + + + + + + (None) + + + + + + + <html><head/><body><p>Note: you only need to set this to access private data.</p></body></html> + + + true + + + + + + Qt::Vertical - - 20 - 40 - - - - - - - - - API Keys - - - - - - &Microsoft Authentication - - - - - - Note: you probably don't need to set this if logging in via Microsoft Authentication already works. - - - Qt::RichText - - - true - - - - - - - (Default) - - - - - - - Enter a custom client ID for Microsoft Authentication here. - - - Qt::RichText - - - true - - - true - - - - - - - - - - true - - - &Modrinth API - - - - - - <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/api/#authentication">documentation</a> for more information.</p></body></html> - - - true - - - - - - - Enter a custom API token for Modrinth here. - - - Qt::RichText - - - true - - - true - - - - - - - true - - - (None) - - - - - - - - - - true - - - &CurseForge Core API - - - - - - Note: you probably don't need to set this if CurseForge already works. - - - - - - - Enter a custom API Key for CurseForge here. - - - Qt::RichText - - - true - - - true - - - - - - - true - - - (Default) - - - - - - - - - - Technic Client ID - - - - - - <html><head/><body><p>Note: you only need to set this to access private data.</p></body></html> - - - - - - - (None) - - - - - - - Enter a custom GUID client ID for Technic here. - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Miscellaneous - - - - - 0 0 - - User Agent - - - - - - - - - Enter a custom User Agent here. The special string $LAUNCHER_VER will be replaced with the version of the launcher. - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - From 06b5ac9a25fdcc29c5555ed64a8dbaf8360f3128 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 21 Mar 2025 15:31:46 +0000 Subject: [PATCH 04/62] Add icons to appearance page Signed-off-by: TheKodeToad --- .../resources/breeze_dark/breeze_dark.qrc | 1 + .../breeze_dark/scalable/appearance.svg | 13 + .../resources/breeze_light/breeze_light.qrc | 1 + .../breeze_light/scalable/appearance.svg | 13 + launcher/resources/flat/flat.qrc | 1 + .../resources/flat/scalable/appearance.svg | 1 + launcher/resources/flat_white/flat_white.qrc | 1 + .../flat_white/scalable/appearance.svg | 1 + launcher/resources/multimc/multimc.qrc | 5 +- .../resources/multimc/scalable/appearance.svg | 2440 +++++++++++++++++ launcher/resources/pe_blue/pe_blue.qrc | 1 + .../resources/pe_blue/scalable/appearance.svg | 70 + launcher/resources/pe_colored/pe_colored.qrc | 1 + .../pe_colored/scalable/appearance.svg | 75 + launcher/resources/pe_dark/pe_dark.qrc | 1 + .../resources/pe_dark/scalable/appearance.svg | 69 + launcher/resources/pe_light/pe_light.qrc | 1 + .../pe_light/scalable/appearance.svg | 70 + launcher/ui/pages/global/AppearancePage.h | 2 +- launcher/ui/pages/global/AppearancePage.ui | 50 +- .../ui/widgets/ThemeCustomizationWidget.ui | 33 + 21 files changed, 2833 insertions(+), 17 deletions(-) create mode 100644 launcher/resources/breeze_dark/scalable/appearance.svg create mode 100644 launcher/resources/breeze_light/scalable/appearance.svg create mode 100644 launcher/resources/flat/scalable/appearance.svg create mode 100644 launcher/resources/flat_white/scalable/appearance.svg create mode 100644 launcher/resources/multimc/scalable/appearance.svg create mode 100644 launcher/resources/pe_blue/scalable/appearance.svg create mode 100644 launcher/resources/pe_colored/scalable/appearance.svg create mode 100644 launcher/resources/pe_dark/scalable/appearance.svg create mode 100644 launcher/resources/pe_light/scalable/appearance.svg diff --git a/launcher/resources/breeze_dark/breeze_dark.qrc b/launcher/resources/breeze_dark/breeze_dark.qrc index 61d82ec30..8fdfdeeb2 100644 --- a/launcher/resources/breeze_dark/breeze_dark.qrc +++ b/launcher/resources/breeze_dark/breeze_dark.qrc @@ -43,5 +43,6 @@ scalable/rename.svg scalable/launch.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/breeze_dark/scalable/appearance.svg b/launcher/resources/breeze_dark/scalable/appearance.svg new file mode 100644 index 000000000..93e6ffa76 --- /dev/null +++ b/launcher/resources/breeze_dark/scalable/appearance.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/launcher/resources/breeze_light/breeze_light.qrc b/launcher/resources/breeze_light/breeze_light.qrc index 2211c7188..6a7120fed 100644 --- a/launcher/resources/breeze_light/breeze_light.qrc +++ b/launcher/resources/breeze_light/breeze_light.qrc @@ -43,5 +43,6 @@ scalable/rename.svg scalable/launch.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/breeze_light/scalable/appearance.svg b/launcher/resources/breeze_light/scalable/appearance.svg new file mode 100644 index 000000000..6e6d64a79 --- /dev/null +++ b/launcher/resources/breeze_light/scalable/appearance.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index 8876027da..b546faec0 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -49,5 +49,6 @@ scalable/rename.svg scalable/server.svg scalable/launch.svg + scalable/appearance.svg diff --git a/launcher/resources/flat/scalable/appearance.svg b/launcher/resources/flat/scalable/appearance.svg new file mode 100644 index 000000000..11dcb3f33 --- /dev/null +++ b/launcher/resources/flat/scalable/appearance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index 83b178cbf..c59bb2ba7 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -49,5 +49,6 @@ scalable/tag.svg scalable/launch.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/flat_white/scalable/appearance.svg b/launcher/resources/flat_white/scalable/appearance.svg new file mode 100644 index 000000000..b20d91f12 --- /dev/null +++ b/launcher/resources/flat_white/scalable/appearance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc index 25edd09e0..80b472917 100644 --- a/launcher/resources/multimc/multimc.qrc +++ b/launcher/resources/multimc/multimc.qrc @@ -247,7 +247,7 @@ scalable/matrix.svg - + scalable/discord.svg @@ -279,7 +279,7 @@ scalable/instances/fox.svg scalable/instances/bee.svg - + 32x32/instances/chicken_legacy.png 128x128/instances/chicken_legacy.png @@ -347,6 +347,7 @@ scalable/export.svg scalable/launch.svg scalable/server.svg + scalable/appearance.svg scalable/instances/quiltmc.svg scalable/instances/fabricmc.svg diff --git a/launcher/resources/multimc/scalable/appearance.svg b/launcher/resources/multimc/scalable/appearance.svg new file mode 100644 index 000000000..429670c36 --- /dev/null +++ b/launcher/resources/multimc/scalable/appearance.svg @@ -0,0 +1,2440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OK + + + + + + + + + + + + 22% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OK + + + + + + + + + + + + 22% + + + + + diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 717d3972e..314fde1a8 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -41,5 +41,6 @@ scalable/launch.svg scalable/shortcut.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/pe_blue/scalable/appearance.svg b/launcher/resources/pe_blue/scalable/appearance.svg new file mode 100644 index 000000000..1d49d9d6f --- /dev/null +++ b/launcher/resources/pe_blue/scalable/appearance.svg @@ -0,0 +1,70 @@ + + + + diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index 023c81e74..484342534 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -41,5 +41,6 @@ scalable/launch.svg scalable/shortcut.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/pe_colored/scalable/appearance.svg b/launcher/resources/pe_colored/scalable/appearance.svg new file mode 100644 index 000000000..ac9cc258a --- /dev/null +++ b/launcher/resources/pe_colored/scalable/appearance.svg @@ -0,0 +1,75 @@ + + + + diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index c97fb469c..06ba97df7 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -41,5 +41,6 @@ scalable/launch.svg scalable/shortcut.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/pe_dark/scalable/appearance.svg b/launcher/resources/pe_dark/scalable/appearance.svg new file mode 100644 index 000000000..b50372fba --- /dev/null +++ b/launcher/resources/pe_dark/scalable/appearance.svg @@ -0,0 +1,69 @@ + + + + diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index b590dd2c6..a1081bcab 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -41,5 +41,6 @@ scalable/launch.svg scalable/shortcut.svg scalable/server.svg + scalable/appearance.svg diff --git a/launcher/resources/pe_light/scalable/appearance.svg b/launcher/resources/pe_light/scalable/appearance.svg new file mode 100644 index 000000000..4f000f452 --- /dev/null +++ b/launcher/resources/pe_light/scalable/appearance.svg @@ -0,0 +1,70 @@ + + + + diff --git a/launcher/ui/pages/global/AppearancePage.h b/launcher/ui/pages/global/AppearancePage.h index fe7cb3da7..2686f52e2 100644 --- a/launcher/ui/pages/global/AppearancePage.h +++ b/launcher/ui/pages/global/AppearancePage.h @@ -58,7 +58,7 @@ class AppearancePage : public QWidget, public BasePage { ~AppearancePage(); QString displayName() const override { return tr("Appearance"); } - QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); } + QIcon icon() const override { return APPLICATION->getThemedIcon("appearance"); } QString id() const override { return "appearance-settings"; } QString helpPage() const override { return "Launcher-settings"; } bool apply() override; diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/pages/global/AppearancePage.ui index d3ddfdb20..676c0659c 100644 --- a/launcher/ui/pages/global/AppearancePage.ui +++ b/launcher/ui/pages/global/AppearancePage.ui @@ -77,17 +77,13 @@ Preview - - - - Icons - - - + + Qt::NoFocus + @@ -102,6 +98,9 @@ + + Qt::NoFocus + @@ -116,6 +115,9 @@ + + Qt::NoFocus + @@ -130,6 +132,9 @@ + + Qt::NoFocus + @@ -144,6 +149,9 @@ + + Qt::NoFocus + @@ -158,6 +166,9 @@ + + Qt::NoFocus + @@ -172,6 +183,9 @@ + + Qt::NoFocus + @@ -186,6 +200,9 @@ + + Qt::NoFocus + @@ -200,6 +217,9 @@ + + Qt::NoFocus + @@ -214,6 +234,9 @@ + + Qt::NoFocus + @@ -231,6 +254,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -242,13 +271,6 @@ - - - - Console - - - diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui index ed05c4292..4ac5706dd 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.ui +++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui @@ -14,6 +14,18 @@ Form + + 0 + + + 0 + + + 0 + + + 0 + @@ -126,6 +138,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -140,12 +158,27 @@ Qt::Horizontal + + + 0 + 0 + + + + iconsComboBox + iconsFolder + widgetStyleComboBox + widgetStyleFolder + backgroundCatComboBox + catPackFolder + refreshButton +
From 99eeef40d9e7c9b80e77f6f2bc20a31d0ad3c531 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 22 Mar 2025 13:58:41 +0000 Subject: [PATCH 05/62] Improve appearance page more Signed-off-by: TheKodeToad --- launcher/ui/pages/global/AppearancePage.cpp | 150 +++- launcher/ui/pages/global/AppearancePage.h | 9 +- launcher/ui/pages/global/AppearancePage.ui | 673 ++++++++++++------ launcher/ui/pages/global/LauncherPage.ui | 448 ++++++------ launcher/ui/themes/CatPack.cpp | 6 +- launcher/ui/themes/CatPack.h | 18 +- launcher/ui/themes/ITheme.h | 1 + launcher/ui/themes/IconTheme.cpp | 17 - launcher/ui/themes/IconTheme.h | 8 +- .../ui/widgets/ThemeCustomizationWidget.cpp | 34 - .../ui/widgets/ThemeCustomizationWidget.h | 2 - .../ui/widgets/ThemeCustomizationWidget.ui | 149 ++-- 12 files changed, 913 insertions(+), 602 deletions(-) diff --git a/launcher/ui/pages/global/AppearancePage.cpp b/launcher/ui/pages/global/AppearancePage.cpp index 7b6c893c7..e9e4ad2b9 100644 --- a/launcher/ui/pages/global/AppearancePage.cpp +++ b/launcher/ui/pages/global/AppearancePage.cpp @@ -1,21 +1,41 @@ #include "AppearancePage.h" #include "ui_AppearancePage.h" -#include -#include -#include +#include +#include +#include "BuildConfig.h" +#include "ui/themes/ITheme.h" +#include "ui/themes/ThemeManager.h" AppearancePage::AppearancePage(QWidget* parent) : QWidget(parent), m_ui(new Ui::AppearancePage) { m_ui->setupUi(this); - defaultFormat = new QTextCharFormat(m_ui->fontPreview->currentCharFormat()); + m_ui->catPreview->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + + defaultFormat = new QTextCharFormat(m_ui->consolePreview->currentCharFormat()); loadSettings(); - connect(m_ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearancePage::updateFontPreview); - connect(m_ui->consoleFont, &QFontComboBox::currentFontChanged, this, &AppearancePage::updateFontPreview); - connect(m_ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentWidgetThemeChanged, this, &AppearancePage::updateFontPreview); - connect(m_ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, APPLICATION, &Application::currentCatChanged); + loadThemeSettings(); + + updateConsolePreview(); + updateCatPreview(); + + connect(m_ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearancePage::updateConsolePreview); + connect(m_ui->consoleFont, &QFontComboBox::currentFontChanged, this, &AppearancePage::updateConsolePreview); + + connect(m_ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyIconTheme); + connect(m_ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyWidgetTheme); + connect(m_ui->catPackComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyCatTheme); + connect(m_ui->catOpacitySlider, &QAbstractSlider::valueChanged, this, &AppearancePage::updateCatPreview); + + connect(m_ui->iconsFolder, &QPushButton::clicked, this, + [] { DesktopServices::openPath(APPLICATION->themeManager()->getIconThemesFolder().path()); }); + connect(m_ui->widgetStyleFolder, &QPushButton::clicked, this, + [] { DesktopServices::openPath(APPLICATION->themeManager()->getApplicationThemesFolder().path()); }); + connect(m_ui->catPackFolder, &QPushButton::clicked, this, + [] { DesktopServices::openPath(APPLICATION->themeManager()->getCatPacksFolder().path()); }); + connect(m_ui->reloadThemesButton, &QPushButton::pressed, this, &AppearancePage::loadThemeSettings); } AppearancePage::~AppearancePage() @@ -40,6 +60,7 @@ void AppearancePage::applySettings() QString consoleFontFamily = m_ui->consoleFont->currentFont().family(); settings->set("ConsoleFont", consoleFontFamily); settings->set("ConsoleFontSize", m_ui->fontSizeBox->value()); + settings->set("CatOpacity", m_ui->catOpacitySlider->value()); } void AppearancePage::loadSettings() @@ -55,16 +76,111 @@ void AppearancePage::loadSettings() } m_ui->fontSizeBox->setValue(fontSize); - updateFontPreview(); + m_ui->catOpacitySlider->setValue(APPLICATION->settings()->get("CatOpacity").toInt()); } -void AppearancePage::updateFontPreview() +void AppearancePage::applyIconTheme(int index) +{ + auto settings = APPLICATION->settings(); + auto originalIconTheme = settings->get("IconTheme").toString(); + auto newIconTheme = m_ui->iconsComboBox->itemData(index).toString(); + if (originalIconTheme != newIconTheme) { + settings->set("IconTheme", newIconTheme); + APPLICATION->themeManager()->applyCurrentlySelectedTheme(); + } +} + +void AppearancePage::applyWidgetTheme(int index) +{ + auto settings = APPLICATION->settings(); + auto originalAppTheme = settings->get("ApplicationTheme").toString(); + auto newAppTheme = m_ui->widgetStyleComboBox->itemData(index).toString(); + if (originalAppTheme != newAppTheme) { + settings->set("ApplicationTheme", newAppTheme); + APPLICATION->themeManager()->applyCurrentlySelectedTheme(); + } + + updateConsolePreview(); +} + +void AppearancePage::applyCatTheme(int index) +{ + auto settings = APPLICATION->settings(); + auto originalCat = settings->get("BackgroundCat").toString(); + auto newCat = m_ui->catPackComboBox->itemData(index).toString(); + if (originalCat != newCat) { + settings->set("BackgroundCat", newCat); + } + + APPLICATION->currentCatChanged(index); + updateCatPreview(); +} + +void AppearancePage::loadThemeSettings() +{ + APPLICATION->themeManager()->refresh(); + + m_ui->iconsComboBox->blockSignals(true); + m_ui->widgetStyleComboBox->blockSignals(true); + m_ui->catPackComboBox->blockSignals(true); + + m_ui->iconsComboBox->clear(); + m_ui->widgetStyleComboBox->clear(); + m_ui->catPackComboBox->clear(); + + const SettingsObjectPtr settings = APPLICATION->settings(); + + const QString currentIconTheme = settings->get("IconTheme").toString(); + const auto iconThemes = APPLICATION->themeManager()->getValidIconThemes(); + + for (int i = 0; i < iconThemes.count(); ++i) { + const IconTheme* theme = iconThemes[i]; + + QIcon iconForComboBox = QIcon(theme->path() + "/scalable/settings"); + m_ui->iconsComboBox->addItem(iconForComboBox, theme->name(), theme->id()); + + if (currentIconTheme == theme->id()) + m_ui->iconsComboBox->setCurrentIndex(i); + } + + const QString currentTheme = settings->get("ApplicationTheme").toString(); + auto themes = APPLICATION->themeManager()->getValidApplicationThemes(); + for (int i = 0; i < themes.count(); ++i) { + ITheme* theme = themes[i]; + + m_ui->widgetStyleComboBox->addItem(theme->name(), theme->id()); + + if (!theme->tooltip().isEmpty()) + m_ui->widgetStyleComboBox->setItemData(i, theme->tooltip(), Qt::ToolTipRole); + + if (currentTheme == theme->id()) + m_ui->widgetStyleComboBox->setCurrentIndex(i); + } + + const QString currentCat = settings->get("BackgroundCat").toString(); + const auto cats = APPLICATION->themeManager()->getValidCatPacks(); + for (int i = 0; i < cats.count(); ++i) { + const CatPack* cat = cats[i]; + + QIcon catIcon = QIcon(QString("%1").arg(cat->path())); + m_ui->catPackComboBox->addItem(catIcon, cat->name(), cat->id()); + + if (currentCat == cat->id()) + m_ui->catPackComboBox->setCurrentIndex(i); + } + + m_ui->iconsComboBox->blockSignals(false); + m_ui->widgetStyleComboBox->blockSignals(false); + m_ui->catPackComboBox->blockSignals(false); +} + +void AppearancePage::updateConsolePreview() { const LogColors& colors = APPLICATION->themeManager()->getLogColors(); int fontSize = m_ui->fontSizeBox->value(); QString fontFamily = m_ui->consoleFont->currentFont().family(); - m_ui->fontPreview->clear(); + m_ui->consolePreview->clear(); defaultFormat->setFont(QFont(fontFamily, fontSize)); auto print = [this, colors](const QString& message, MessageLevel::Enum level) { @@ -80,7 +196,7 @@ void AppearancePage::updateFontPreview() format.setForeground(fg); // append a paragraph/line - auto workCursor = m_ui->fontPreview->textCursor(); + auto workCursor = m_ui->consolePreview->textCursor(); workCursor.movePosition(QTextCursor::End); workCursor.insertText(message, format); workCursor.insertBlock(); @@ -102,3 +218,13 @@ void AppearancePage::updateFontPreview() print(tr("[Test/DEBUG] A secret debugging message..."), MessageLevel::Debug); print(tr("[Test/FATAL] A terrifying fatal error!"), MessageLevel::Fatal); } + +void AppearancePage::updateCatPreview() +{ + QIcon catPackIcon(APPLICATION->themeManager()->getCatPack()); + m_ui->catPreview->setIcon(catPackIcon); + + auto effect = dynamic_cast(m_ui->catPreview->graphicsEffect()); + if (effect) + effect->setOpacity(m_ui->catOpacitySlider->value() / 100.0); +} diff --git a/launcher/ui/pages/global/AppearancePage.h b/launcher/ui/pages/global/AppearancePage.h index 2686f52e2..f964d5f7c 100644 --- a/launcher/ui/pages/global/AppearancePage.h +++ b/launcher/ui/pages/global/AppearancePage.h @@ -67,7 +67,14 @@ class AppearancePage : public QWidget, public BasePage { private: void applySettings(); void loadSettings(); - void updateFontPreview(); + + void applyIconTheme(int index); + void applyWidgetTheme(int index); + void applyCatTheme(int index); + void loadThemeSettings(); + + void updateConsolePreview(); + void updateCatPreview(); private: Ui::AppearancePage* m_ui; diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/pages/global/AppearancePage.ui index 676c0659c..ad2aba7e8 100644 --- a/launcher/ui/pages/global/AppearancePage.ui +++ b/launcher/ui/pages/global/AppearancePage.ui @@ -10,299 +10,522 @@ 700 + + + 300 + 0 + + Form - + - + - Theme + + + + false - - - - - - - - - - 0 - 0 - - - - &Fonts - - - - - - - 0 - 0 - - - - - - - - 5 - - - 16 - - - 11 - - - - - - - Monospace Font - - - - - - - - - - Preview - - - - - - - - Qt::NoFocus + + + + + View cat packs folder. - - - - - .. - - - true + Open Folder - - - - Qt::NoFocus + + + + View widget themes folder. - - - - - .. - - - true + Open Folder - - - - Qt::NoFocus + + + + View icon themes folder. - - - - - .. - - - true + Open Folder - - - - Qt::NoFocus - + + - + &Cat Pack - - - .. - - - true + + catPackComboBox - - + + + + + + + + 0 + 0 + + - Qt::NoFocus - - - - - - - .. - - - true + Qt::StrongFocus - - + + + + + 0 + 0 + + - Qt::NoFocus - - - - - - - .. - - - true + Qt::StrongFocus - - - - Qt::NoFocus + + + + + 0 + 0 + - - - - - .. - - - true + Reload All - - - - Qt::NoFocus - + + - + Theme - - - .. - - - true + + widgetStyleComboBox - - - - Qt::NoFocus - + + - + &Icons - - - .. - - - true + + iconsComboBox - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + Qt::Horizontal - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - false - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + Console Font + + + + + 300 + 16777215 + + + + + + + + + + 5 + + + 16 + + + 11 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + + + Cat Opacity + + + + + + + + 300 + 16777215 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + 100 + + + Qt::Horizontal + + + 5 + + + + + + + Transparent + + + + + + + true + + + Opaque + + + + + + + + + + + + + Preview + + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + + + + 128 + 256 + + + + true + + + + + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAsNeeded + + + false + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + - - - ThemeCustomizationWidget - QWidget -
ui/widgets/ThemeCustomizationWidget.h
- 1 -
-
+ + widgetStyleComboBox + widgetStyleFolder + iconsComboBox + iconsFolder + catPackComboBox + catPackFolder + consoleFont + fontSizeBox + catOpacitySlider + consolePreview +
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index f4d329c44..da2f6d5f2 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -31,7 +31,7 @@ 0 0 563 - 1293 + 1336 @@ -72,11 +72,20 @@ - + - Qt::Horizontal + Qt::Vertical - + + QSizePolicy::Fixed + + + + 0 + 6 + + + @@ -104,6 +113,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + @@ -112,37 +137,26 @@ - - - - - Set it to 0 to only check on launch - - - h - - - 0 - - - 168 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + + + + 0 + 0 + + + + Set it to 0 to only check on launch + + + h + + + 0 + + + 168 + + @@ -163,29 +177,13 @@ - - + + Browse - - - - - - - - - - &Skins - - - skinsDirTextBox - - - @@ -196,19 +194,10 @@ - - - - - - - - + + - &Java - - - javaDirTextBox + Browse @@ -222,29 +211,6 @@ - - - - - - - - - - - - - Browse - - - - - - - Browse - - - @@ -252,6 +218,22 @@ + + + + + + + Browse + + + + + + + + + @@ -262,13 +244,39 @@ - - + + + + &Java + + + javaDirTextBox + + + + + + + + Browse + + + + + + + &Skins + + + skinsDirTextBox + + + @@ -276,13 +284,16 @@ + + + - Mod Management + Mods @@ -350,7 +361,7 @@ When creating a new modpack instance, do not suggest updating existing instances instead. - Ask whether to update an existing instance when installing modpacks + Suggest to update an existing instance @@ -374,40 +385,45 @@ - - - - - - 0 - 0 - - - - lines - - - 10000 - - - 1000000 - - - 10000 - - - 100000 - - - - - - - Qt::Horizontal - - - - + + + + 0 + 0 + + + + lines + + + 10000 + + + 1000000 + + + 10000 + + + 100000 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + @@ -433,28 +449,33 @@ - - - - - 1 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + + + + 0 + 0 + + + + 1 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + @@ -464,28 +485,33 @@ - - - - - 1 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + + + + 0 + 0 + + + + 1 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + @@ -495,28 +521,33 @@ - - - - - 0 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + + + + 0 + 0 + + + + 0 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + @@ -529,28 +560,17 @@ - - - - - s - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - + + + + 0 + 0 + + + + s + + diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 85eb85a18..416b86139 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -43,7 +43,7 @@ #include "FileSystem.h" #include "Json.h" -QString BasicCatPack::path() +QString BasicCatPack::path() const { const auto now = QDate::currentDate(); const auto birthday = QDate(now.year(), 11, 1); @@ -100,12 +100,12 @@ QDate ensureDay(int year, int month, int day) return QDate(year, month, day); } -QString JsonCatPack::path() +QString JsonCatPack::path() const { return path(QDate::currentDate()); } -QString JsonCatPack::path(QDate now) +QString JsonCatPack::path(QDate now) const { for (auto var : m_variants) { QDate startDate = ensureDay(now.year(), var.startTime.month, var.startTime.day); diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index 5a13d0cef..e0e34f86e 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -43,18 +43,18 @@ class CatPack { public: virtual ~CatPack() {} - virtual QString id() = 0; - virtual QString name() = 0; - virtual QString path() = 0; + virtual QString id() const = 0; + virtual QString name() const = 0; + virtual QString path() const = 0; }; class BasicCatPack : public CatPack { public: BasicCatPack(QString id, QString name) : m_id(id), m_name(name) {} BasicCatPack(QString id) : BasicCatPack(id, id) {} - virtual QString id() override { return m_id; } - virtual QString name() override { return m_name; } - virtual QString path() override; + virtual QString id() const override { return m_id; } + virtual QString name() const override { return m_name; } + virtual QString path() const override; protected: QString m_id; @@ -65,7 +65,7 @@ class FileCatPack : public BasicCatPack { public: FileCatPack(QString id, QFileInfo& fileInfo) : BasicCatPack(id), m_path(fileInfo.absoluteFilePath()) {} FileCatPack(QFileInfo& fileInfo) : FileCatPack(fileInfo.baseName(), fileInfo) {} - virtual QString path() { return m_path; } + virtual QString path() const { return m_path; } private: QString m_path; @@ -83,8 +83,8 @@ class JsonCatPack : public BasicCatPack { PartialDate endTime; }; JsonCatPack(QFileInfo& manifestInfo); - virtual QString path() override; - QString path(QDate now); + virtual QString path() const override; + QString path(QDate now) const; private: QString m_default_path; diff --git a/launcher/ui/themes/ITheme.h b/launcher/ui/themes/ITheme.h index 7dc5fc64a..a3dd14d09 100644 --- a/launcher/ui/themes/ITheme.h +++ b/launcher/ui/themes/ITheme.h @@ -47,6 +47,7 @@ struct LogColors { }; // TODO: rename to Theme; this is not an interface as it contains method implementations +// TODO: make methods const class ITheme { public: virtual ~ITheme() {} diff --git a/launcher/ui/themes/IconTheme.cpp b/launcher/ui/themes/IconTheme.cpp index 4bd889854..6415c5148 100644 --- a/launcher/ui/themes/IconTheme.cpp +++ b/launcher/ui/themes/IconTheme.cpp @@ -21,8 +21,6 @@ #include #include -IconTheme::IconTheme(const QString& id, const QString& path) : m_id(id), m_path(path) {} - bool IconTheme::load() { const QString path = m_path + "/index.theme"; @@ -36,18 +34,3 @@ bool IconTheme::load() settings.endGroup(); return !m_name.isNull(); } - -QString IconTheme::id() -{ - return m_id; -} - -QString IconTheme::path() -{ - return m_path; -} - -QString IconTheme::name() -{ - return m_name; -} diff --git a/launcher/ui/themes/IconTheme.h b/launcher/ui/themes/IconTheme.h index 4e466c6ae..f49e39289 100644 --- a/launcher/ui/themes/IconTheme.h +++ b/launcher/ui/themes/IconTheme.h @@ -22,13 +22,13 @@ class IconTheme { public: - IconTheme(const QString& id, const QString& path); + IconTheme(const QString& id, const QString& path) : m_id(id), m_path(path) {} IconTheme() = default; bool load(); - QString id(); - QString path(); - QString name(); + QString id() const { return m_id; } + QString path() const { return m_path; } + QString name() const { return m_name; } private: QString m_id; diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index 097678b8d..b9412a10a 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -49,40 +49,6 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget() delete ui; } -/// -/// The layout was not quite right, so currently this just disables the UI elements, which should be hidden instead -/// TODO FIXME -/// -/// Original Method One: -/// ui->iconsComboBox->setVisible(features& ThemeFields::ICONS); -/// ui->iconsLabel->setVisible(features& ThemeFields::ICONS); -/// ui->widgetStyleComboBox->setVisible(features& ThemeFields::WIDGETS); -/// ui->widgetThemeLabel->setVisible(features& ThemeFields::WIDGETS); -/// ui->backgroundCatComboBox->setVisible(features& ThemeFields::CAT); -/// ui->backgroundCatLabel->setVisible(features& ThemeFields::CAT); -/// -/// original Method Two: -/// if (!(features & ThemeFields::ICONS)) { -/// ui->formLayout->setRowVisible(0, false); -/// } -/// if (!(features & ThemeFields::WIDGETS)) { -/// ui->formLayout->setRowVisible(1, false); -/// } -/// if (!(features & ThemeFields::CAT)) { -/// ui->formLayout->setRowVisible(2, false); -/// } -/// -/// -void ThemeCustomizationWidget::showFeatures(ThemeFields features) -{ - ui->iconsComboBox->setEnabled(features & ThemeFields::ICONS); - ui->iconsLabel->setEnabled(features & ThemeFields::ICONS); - ui->widgetStyleComboBox->setEnabled(features & ThemeFields::WIDGETS); - ui->widgetStyleLabel->setEnabled(features & ThemeFields::WIDGETS); - ui->backgroundCatComboBox->setEnabled(features & ThemeFields::CAT); - ui->backgroundCatLabel->setEnabled(features & ThemeFields::CAT); -} - void ThemeCustomizationWidget::applyIconTheme(int index) { auto settings = APPLICATION->settings(); diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h index 6977b8495..d5b160f3f 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/ThemeCustomizationWidget.h @@ -33,8 +33,6 @@ class ThemeCustomizationWidget : public QWidget { explicit ThemeCustomizationWidget(QWidget* parent = nullptr); ~ThemeCustomizationWidget() override; - void showFeatures(ThemeFields features); - void applySettings(); void loadSettings(); diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui index 4ac5706dd..3e2808a48 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.ui +++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui @@ -7,68 +7,13 @@ 0 0 400 - 191 + 168 Form - - 0 - - - 0 - - - 0 - - - 0 - - - - - View icon themes folder. - - - Open Folder - - - - - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - C&at - - - backgroundCatComboBox - - - - - - - View cat packs folder. - - - Open Folder - - - - - - - &Icons - - - iconsComboBox - - - @@ -102,22 +47,6 @@ - - - - - 0 - 0 - - - - Qt::StrongFocus - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - @@ -131,7 +60,17 @@ - + + + + View icon themes folder. + + + Open Folder + + + + @@ -146,13 +85,6 @@ - - - - Refresh All - - - @@ -168,6 +100,62 @@ + + + + The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. + + + C&at + + + backgroundCatComboBox + + + + + + + &Icons + + + iconsComboBox + + + + + + + View cat packs folder. + + + Open Folder + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. + + + + + + + Refresh All + + + @@ -177,7 +165,6 @@ widgetStyleFolder backgroundCatComboBox catPackFolder - refreshButton From dd3a4023c92116b31299614c5a8dbd0a4ee94fba Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 22 Mar 2025 16:03:23 +0000 Subject: [PATCH 06/62] Move cat to right and use QPushButtons for browse Signed-off-by: TheKodeToad --- launcher/ui/pages/global/AppearancePage.ui | 439 ++++++++++----------- launcher/ui/pages/global/LauncherPage.ui | 162 ++++---- 2 files changed, 299 insertions(+), 302 deletions(-) diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/pages/global/AppearancePage.ui index ad2aba7e8..455bf4c1f 100644 --- a/launcher/ui/pages/global/AppearancePage.ui +++ b/launcher/ui/pages/global/AppearancePage.ui @@ -19,9 +19,9 @@ Form - + - + @@ -135,13 +135,15 @@ - - - - Qt::Horizontal - - - + + + + + + + + + @@ -271,7 +273,213 @@ - + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAsNeeded + + + false + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + @@ -297,216 +505,6 @@ - - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - false - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - @@ -524,7 +522,6 @@ consoleFont fontSizeBox catOpacitySlider - consolePreview diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index da2f6d5f2..24678549f 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -167,22 +167,18 @@ Folders - - + + - &Downloads + &Mods - downloadsDirTextBox + modsDirTextBox - - - - Browse - - + + @@ -194,79 +190,16 @@ - - + + - Browse - - - - - - - &Mods + &Downloads - modsDirTextBox + downloadsDirTextBox - - - - Browse - - - - - - - - - - Browse - - - - - - - - - - - - - I&nstances - - - instDirTextBox - - - - - - - &Java - - - javaDirTextBox - - - - - - - - - - Browse - - - - - - @@ -277,15 +210,82 @@ - - + + + + I&nstances + + + instDirTextBox + + + + + + + + + + + + + + + + &Java + + + javaDirTextBox + + + + + + + + + + + Browse - - + + + + Browse + + + + + + + Browse + + + + + + + Browse + + + + + + + Browse + + + + + + + Browse + + From 3a508bdc7821500f0d4f267286bd76d505380f2e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 22 Mar 2025 16:48:29 +0000 Subject: [PATCH 07/62] Change slider behaviour to jumping directly when clicking Signed-off-by: TheKodeToad --- launcher/ui/pages/global/AppearancePage.ui | 3 --- launcher/ui/themes/HintOverrideProxyStyle.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/pages/global/AppearancePage.ui index 455bf4c1f..5b159ff15 100644 --- a/launcher/ui/pages/global/AppearancePage.ui +++ b/launcher/ui/pages/global/AppearancePage.ui @@ -238,9 +238,6 @@ Qt::Horizontal - - 5 - diff --git a/launcher/ui/themes/HintOverrideProxyStyle.cpp b/launcher/ui/themes/HintOverrideProxyStyle.cpp index 80e821349..2567a35f4 100644 --- a/launcher/ui/themes/HintOverrideProxyStyle.cpp +++ b/launcher/ui/themes/HintOverrideProxyStyle.cpp @@ -26,5 +26,11 @@ int HintOverrideProxyStyle::styleHint(QStyle::StyleHint hint, if (hint == QStyle::SH_ItemView_ActivateItemOnSingleClick) return 0; + if (hint == QStyle::SH_Slider_AbsoluteSetButtons) + return Qt::LeftButton | Qt::MiddleButton; + + if (hint == QStyle::SH_Slider_PageSetButtons) + return Qt::RightButton; + return QProxyStyle::styleHint(hint, option, widget, returnData); } From a1baa5ff479bb227589509718c379462dfb74bfb Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 22 Mar 2025 17:00:02 +0000 Subject: [PATCH 08/62] Use OK and Cancel instead of Close in Settings dialog Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 22 +++++++++++----------- launcher/ui/pagedialog/PageDialog.h | 5 ++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index d211cb4d3..275908efa 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -29,34 +29,34 @@ PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidget* parent) : QDialog(parent) { setWindowTitle(pageProvider->dialogTitle()); - m_container = new PageContainer(pageProvider, defaultId, this); + m_container = new PageContainer(pageProvider, std::move(defaultId), this); - QVBoxLayout* mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_container); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); setLayout(mainLayout); - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close); - buttons->button(QDialogButtonBox::Close)->setDefault(true); - buttons->button(QDialogButtonBox::Close)->setText(tr("Close")); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttons->button(QDialogButtonBox::Ok)->setDefault(true); buttons->button(QDialogButtonBox::Help)->setText(tr("Help")); buttons->setContentsMargins(6, 0, 6, 0); m_container->addButtons(buttons); - connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close())); - connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help())); + connect(buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &PageDialog::applyAndClose); + connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &PageDialog::reject); + connect(buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help); restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } - -void PageDialog::closeEvent(QCloseEvent* event) +void PageDialog::applyAndClose() { - qDebug() << "Paged dialog close requested"; + qDebug() << "Paged dialog apply and close requested"; if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; - QDialog::closeEvent(event); + close(); } + } diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index aa50bc5e1..337cfd3a3 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -25,9 +25,8 @@ class PageDialog : public QDialog { explicit PageDialog(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0); virtual ~PageDialog() {} - private slots: - virtual void closeEvent(QCloseEvent* event); - private: + void applyAndClose(); + PageContainer* m_container; }; From 411161fe495c4dad2155acc8fdef86fe0ecc5a18 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 22 Mar 2025 22:31:57 +0000 Subject: [PATCH 09/62] Use same UI for appearance page and wizard Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 10 +- launcher/ui/pages/global/AppearancePage.h | 32 +- launcher/ui/setupwizard/ThemeWizardPage.cpp | 31 -- launcher/ui/setupwizard/ThemeWizardPage.h | 27 +- launcher/ui/setupwizard/ThemeWizardPage.ui | 371 --------------- .../AppearanceWidget.cpp} | 149 +++--- ...stomizationWidget.h => AppearanceWidget.h} | 41 +- .../AppearanceWidget.ui} | 426 +++++++++--------- .../ui/widgets/ThemeCustomizationWidget.cpp | 163 ------- 9 files changed, 361 insertions(+), 889 deletions(-) delete mode 100644 launcher/ui/setupwizard/ThemeWizardPage.ui rename launcher/ui/{pages/global/AppearancePage.cpp => widgets/AppearanceWidget.cpp} (59%) rename launcher/ui/widgets/{ThemeCustomizationWidget.h => AppearanceWidget.h} (59%) rename launcher/ui/{pages/global/AppearancePage.ui => widgets/AppearanceWidget.ui} (56%) delete mode 100644 launcher/ui/widgets/ThemeCustomizationWidget.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 0c07ca618..319f000cc 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -843,7 +843,6 @@ SET(LAUNCHER_SOURCES ui/setupwizard/LanguageWizardPage.h ui/setupwizard/PasteWizardPage.cpp ui/setupwizard/PasteWizardPage.h - ui/setupwizard/ThemeWizardPage.cpp ui/setupwizard/ThemeWizardPage.h ui/setupwizard/AutoJavaWizardPage.cpp ui/setupwizard/AutoJavaWizardPage.h @@ -937,7 +936,6 @@ SET(LAUNCHER_SOURCES ui/pages/global/MinecraftPage.h ui/pages/global/LauncherPage.cpp ui/pages/global/LauncherPage.h - ui/pages/global/AppearancePage.cpp ui/pages/global/AppearancePage.h ui/pages/global/ProxyPage.cpp ui/pages/global/ProxyPage.h @@ -1132,8 +1130,8 @@ SET(LAUNCHER_SOURCES ui/widgets/ProgressWidget.cpp ui/widgets/WideBar.h ui/widgets/WideBar.cpp - ui/widgets/ThemeCustomizationWidget.h - ui/widgets/ThemeCustomizationWidget.cpp + ui/widgets/AppearanceWidget.h + ui/widgets/AppearanceWidget.cpp ui/widgets/MinecraftSettingsWidget.h ui/widgets/MinecraftSettingsWidget.cpp ui/widgets/JavaSettingsWidget.h @@ -1175,11 +1173,9 @@ qt_wrap_ui(LAUNCHER_UI ui/setupwizard/PasteWizardPage.ui ui/setupwizard/AutoJavaWizardPage.ui ui/setupwizard/LoginWizardPage.ui - ui/setupwizard/ThemeWizardPage.ui ui/pages/global/AccountListPage.ui ui/pages/global/JavaPage.ui ui/pages/global/LauncherPage.ui - ui/pages/global/AppearancePage.ui ui/pages/global/APIPage.ui ui/pages/global/ProxyPage.ui ui/pages/global/ExternalToolsPage.ui @@ -1210,7 +1206,7 @@ qt_wrap_ui(LAUNCHER_UI ui/widgets/InfoFrame.ui ui/widgets/ModFilterWidget.ui ui/widgets/SubTaskProgressBar.ui - ui/widgets/ThemeCustomizationWidget.ui + ui/widgets/AppearanceWidget.ui ui/widgets/MinecraftSettingsWidget.ui ui/widgets/JavaSettingsWidget.ui ui/dialogs/CopyInstanceDialog.ui diff --git a/launcher/ui/pages/global/AppearancePage.h b/launcher/ui/pages/global/AppearancePage.h index f964d5f7c..bf58ebb53 100644 --- a/launcher/ui/pages/global/AppearancePage.h +++ b/launcher/ui/pages/global/AppearancePage.h @@ -40,43 +40,29 @@ #include #include +#include #include "java/JavaChecker.h" #include "ui/pages/BasePage.h" class QTextCharFormat; class SettingsObject; -namespace Ui { -class AppearancePage; -} - -class AppearancePage : public QWidget, public BasePage { +class AppearancePage : public AppearanceWidget, public BasePage { Q_OBJECT public: - explicit AppearancePage(QWidget* parent = 0); - ~AppearancePage(); + explicit AppearancePage(QWidget *parent = nullptr) : AppearanceWidget(false, parent) {} QString displayName() const override { return tr("Appearance"); } QIcon icon() const override { return APPLICATION->getThemedIcon("appearance"); } QString id() const override { return "appearance-settings"; } QString helpPage() const override { return "Launcher-settings"; } - bool apply() override; - void retranslate() override; - private: - void applySettings(); - void loadSettings(); + bool apply() override + { + applySettings(); + return true; + } - void applyIconTheme(int index); - void applyWidgetTheme(int index); - void applyCatTheme(int index); - void loadThemeSettings(); - - void updateConsolePreview(); - void updateCatPreview(); - - private: - Ui::AppearancePage* m_ui; - QTextCharFormat* defaultFormat; + void retranslate() override { retranslateUi(); } }; diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp index fe11ed9ae..c97037f9f 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.cpp +++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp @@ -34,37 +34,6 @@ ThemeWizardPage::ThemeWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(n updateIcons(); updateCat(); } - -ThemeWizardPage::~ThemeWizardPage() -{ - delete ui; -} - -void ThemeWizardPage::updateIcons() -{ - qDebug() << "Setting Icons"; - ui->previewIconButton0->setIcon(APPLICATION->getThemedIcon("new")); - ui->previewIconButton1->setIcon(APPLICATION->getThemedIcon("centralmods")); - ui->previewIconButton2->setIcon(APPLICATION->getThemedIcon("viewfolder")); - ui->previewIconButton3->setIcon(APPLICATION->getThemedIcon("launch")); - ui->previewIconButton4->setIcon(APPLICATION->getThemedIcon("copy")); - ui->previewIconButton5->setIcon(APPLICATION->getThemedIcon("export")); - ui->previewIconButton6->setIcon(APPLICATION->getThemedIcon("delete")); - ui->previewIconButton7->setIcon(APPLICATION->getThemedIcon("about")); - ui->previewIconButton8->setIcon(APPLICATION->getThemedIcon("settings")); - ui->previewIconButton9->setIcon(APPLICATION->getThemedIcon("cat")); - update(); - repaint(); - parentWidget()->update(); -} - -void ThemeWizardPage::updateCat() -{ - qDebug() << "Setting Cat"; - ui->catImagePreviewButton->setIcon(QIcon(QString(R"(%1)").arg(APPLICATION->themeManager()->getCatPack()))); -} - -void ThemeWizardPage::retranslate() { ui->retranslateUi(this); } diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h index f3d40b6d8..8ea438398 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.h +++ b/launcher/ui/setupwizard/ThemeWizardPage.h @@ -17,27 +17,30 @@ */ #pragma once +#include +#include #include #include "BaseWizardPage.h" -namespace Ui { -class ThemeWizardPage; -} - class ThemeWizardPage : public BaseWizardPage { Q_OBJECT public: - explicit ThemeWizardPage(QWidget* parent = nullptr); - ~ThemeWizardPage(); + ThemeWizardPage(QWidget* parent = nullptr) : BaseWizardPage(parent) + { + auto layout = new QVBoxLayout(this); + layout->addWidget(&widget); + layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + layout->setContentsMargins(0, 0, 0, 0); + setLayout(layout); + + setTitle(tr("Appearance")); + setSubTitle(tr("Select theme and icons to use")); + } bool validatePage() override { return true; }; - void retranslate() override; - - private slots: - void updateIcons(); - void updateCat(); + void retranslate() override { widget.retranslateUi(); } private: - Ui::ThemeWizardPage* ui; + AppearanceWidget widget{true}; }; diff --git a/launcher/ui/setupwizard/ThemeWizardPage.ui b/launcher/ui/setupwizard/ThemeWizardPage.ui deleted file mode 100644 index 01394ea40..000000000 --- a/launcher/ui/setupwizard/ThemeWizardPage.ui +++ /dev/null @@ -1,371 +0,0 @@ - - - ThemeWizardPage - - - - 0 - 0 - 510 - 552 - - - - WizardPage - - - - - - Select the Theme you wish to use - - - - - - - - 0 - 100 - - - - - - - - Hint: The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - true - - - - - - - Qt::Horizontal - - - - - - - Preview: - - - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 30 - 30 - - - - - .. - - - false - - - true - - - - - - - - - - 0 - 256 - - - - The cat appears in the background and does not serve a purpose, it is purely visual. - - - - - - - 256 - 256 - - - - true - - - - - - - Qt::Vertical - - - - 20 - 193 - - - - - - - - - ThemeCustomizationWidget - QWidget -
ui/widgets/ThemeCustomizationWidget.h
-
-
- - -
diff --git a/launcher/ui/pages/global/AppearancePage.cpp b/launcher/ui/widgets/AppearanceWidget.cpp similarity index 59% rename from launcher/ui/pages/global/AppearancePage.cpp rename to launcher/ui/widgets/AppearanceWidget.cpp index e9e4ad2b9..f9475cbbd 100644 --- a/launcher/ui/pages/global/AppearancePage.cpp +++ b/launcher/ui/widgets/AppearanceWidget.cpp @@ -1,5 +1,41 @@ -#include "AppearancePage.h" -#include "ui_AppearancePage.h" +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2025 TheKodeToad + * Copyright (C) 2022 Tayou + * + * 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 . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppearanceWidget.h" +#include "ui_AppearanceWidget.h" #include #include @@ -7,27 +43,38 @@ #include "ui/themes/ITheme.h" #include "ui/themes/ThemeManager.h" -AppearancePage::AppearancePage(QWidget* parent) : QWidget(parent), m_ui(new Ui::AppearancePage) +AppearanceWidget::AppearanceWidget(bool themesOnly, QWidget* parent) + : QWidget(parent), m_ui(new Ui::AppearanceWidget), m_themesOnly(themesOnly) { m_ui->setupUi(this); m_ui->catPreview->setGraphicsEffect(new QGraphicsOpacityEffect(this)); - defaultFormat = new QTextCharFormat(m_ui->consolePreview->currentCharFormat()); + m_defaultFormat = new QTextCharFormat(m_ui->consolePreview->currentCharFormat()); - loadSettings(); - loadThemeSettings(); + if (themesOnly) { + m_ui->catPackLabel->hide(); + m_ui->catPackComboBox->hide(); + m_ui->catPackFolder->hide(); + m_ui->settingsBox->hide(); + m_ui->consolePreview->hide(); + m_ui->catPreview->hide(); + loadThemeSettings(); + } else { + loadSettings(); + loadThemeSettings(); - updateConsolePreview(); - updateCatPreview(); + updateConsolePreview(); + updateCatPreview(); + } - connect(m_ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearancePage::updateConsolePreview); - connect(m_ui->consoleFont, &QFontComboBox::currentFontChanged, this, &AppearancePage::updateConsolePreview); + connect(m_ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearanceWidget::updateConsolePreview); + connect(m_ui->consoleFont, &QFontComboBox::currentFontChanged, this, &AppearanceWidget::updateConsolePreview); - connect(m_ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyIconTheme); - connect(m_ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyWidgetTheme); - connect(m_ui->catPackComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearancePage::applyCatTheme); - connect(m_ui->catOpacitySlider, &QAbstractSlider::valueChanged, this, &AppearancePage::updateCatPreview); + connect(m_ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearanceWidget::applyIconTheme); + connect(m_ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearanceWidget::applyWidgetTheme); + connect(m_ui->catPackComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AppearanceWidget::applyCatTheme); + connect(m_ui->catOpacitySlider, &QAbstractSlider::valueChanged, this, &AppearanceWidget::updateCatPreview); connect(m_ui->iconsFolder, &QPushButton::clicked, this, [] { DesktopServices::openPath(APPLICATION->themeManager()->getIconThemesFolder().path()); }); @@ -35,26 +82,15 @@ AppearancePage::AppearancePage(QWidget* parent) : QWidget(parent), m_ui(new Ui:: [] { DesktopServices::openPath(APPLICATION->themeManager()->getApplicationThemesFolder().path()); }); connect(m_ui->catPackFolder, &QPushButton::clicked, this, [] { DesktopServices::openPath(APPLICATION->themeManager()->getCatPacksFolder().path()); }); - connect(m_ui->reloadThemesButton, &QPushButton::pressed, this, &AppearancePage::loadThemeSettings); + connect(m_ui->reloadThemesButton, &QPushButton::pressed, this, &AppearanceWidget::loadThemeSettings); } -AppearancePage::~AppearancePage() +AppearanceWidget::~AppearanceWidget() { delete m_ui; } -bool AppearancePage::apply() -{ - applySettings(); - return true; -} - -void AppearancePage::retranslate() -{ - m_ui->retranslateUi(this); -} - -void AppearancePage::applySettings() +void AppearanceWidget::applySettings() { SettingsObjectPtr settings = APPLICATION->settings(); QString consoleFontFamily = m_ui->consoleFont->currentFont().family(); @@ -63,7 +99,7 @@ void AppearancePage::applySettings() settings->set("CatOpacity", m_ui->catOpacitySlider->value()); } -void AppearancePage::loadSettings() +void AppearanceWidget::loadSettings() { QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); QFont consoleFont(fontFamily); @@ -79,7 +115,12 @@ void AppearancePage::loadSettings() m_ui->catOpacitySlider->setValue(APPLICATION->settings()->get("CatOpacity").toInt()); } -void AppearancePage::applyIconTheme(int index) +void AppearanceWidget::retranslateUi() +{ + m_ui->retranslateUi(this); +} + +void AppearanceWidget::applyIconTheme(int index) { auto settings = APPLICATION->settings(); auto originalIconTheme = settings->get("IconTheme").toString(); @@ -90,7 +131,7 @@ void AppearancePage::applyIconTheme(int index) } } -void AppearancePage::applyWidgetTheme(int index) +void AppearanceWidget::applyWidgetTheme(int index) { auto settings = APPLICATION->settings(); auto originalAppTheme = settings->get("ApplicationTheme").toString(); @@ -103,7 +144,7 @@ void AppearancePage::applyWidgetTheme(int index) updateConsolePreview(); } -void AppearancePage::applyCatTheme(int index) +void AppearanceWidget::applyCatTheme(int index) { auto settings = APPLICATION->settings(); auto originalCat = settings->get("BackgroundCat").toString(); @@ -116,7 +157,7 @@ void AppearancePage::applyCatTheme(int index) updateCatPreview(); } -void AppearancePage::loadThemeSettings() +void AppearanceWidget::loadThemeSettings() { APPLICATION->themeManager()->refresh(); @@ -157,16 +198,18 @@ void AppearancePage::loadThemeSettings() m_ui->widgetStyleComboBox->setCurrentIndex(i); } - const QString currentCat = settings->get("BackgroundCat").toString(); - const auto cats = APPLICATION->themeManager()->getValidCatPacks(); - for (int i = 0; i < cats.count(); ++i) { - const CatPack* cat = cats[i]; + if (!m_themesOnly) { + const QString currentCat = settings->get("BackgroundCat").toString(); + const auto cats = APPLICATION->themeManager()->getValidCatPacks(); + for (int i = 0; i < cats.count(); ++i) { + const CatPack* cat = cats[i]; - QIcon catIcon = QIcon(QString("%1").arg(cat->path())); - m_ui->catPackComboBox->addItem(catIcon, cat->name(), cat->id()); + QIcon catIcon = QIcon(QString("%1").arg(cat->path())); + m_ui->catPackComboBox->addItem(catIcon, cat->name(), cat->id()); - if (currentCat == cat->id()) - m_ui->catPackComboBox->setCurrentIndex(i); + if (currentCat == cat->id()) + m_ui->catPackComboBox->setCurrentIndex(i); + } } m_ui->iconsComboBox->blockSignals(false); @@ -174,17 +217,17 @@ void AppearancePage::loadThemeSettings() m_ui->catPackComboBox->blockSignals(false); } -void AppearancePage::updateConsolePreview() +void AppearanceWidget::updateConsolePreview() { const LogColors& colors = APPLICATION->themeManager()->getLogColors(); int fontSize = m_ui->fontSizeBox->value(); QString fontFamily = m_ui->consoleFont->currentFont().family(); m_ui->consolePreview->clear(); - defaultFormat->setFont(QFont(fontFamily, fontSize)); + m_defaultFormat->setFont(QFont(fontFamily, fontSize)); auto print = [this, colors](const QString& message, MessageLevel::Enum level) { - QTextCharFormat format(*defaultFormat); + QTextCharFormat format(*m_defaultFormat); QColor bg = colors.background.value(level); QColor fg = colors.foreground.value(level); @@ -202,24 +245,24 @@ void AppearancePage::updateConsolePreview() workCursor.insertBlock(); }; - print(QString("%1 version: %2 (%3)\n") - .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString(), BuildConfig.BUILD_PLATFORM), + print(QString("%1 version: %2\n") + .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()), MessageLevel::Launcher); QDate today = QDate::currentDate(); if (today.month() == 10 && today.day() == 31) - print(tr("[Test/ERROR] OOoooOOOoooo! A spooky error!"), MessageLevel::Error); + print(tr("[ERROR] OOoooOOOoooo! A spooky error!"), MessageLevel::Error); else - print(tr("[Test/ERROR] A spooky error!"), MessageLevel::Error); + print(tr("[ERROR] A spooky error!"), MessageLevel::Error); - print(tr("[Test/INFO] A harmless message..."), MessageLevel::Info); - print(tr("[Test/WARN] A not so spooky warning."), MessageLevel::Warning); - print(tr("[Test/DEBUG] A secret debugging message..."), MessageLevel::Debug); - print(tr("[Test/FATAL] A terrifying fatal error!"), MessageLevel::Fatal); + print(tr("[INFO] A harmless message..."), MessageLevel::Info); + print(tr("[WARN] A not so spooky warning."), MessageLevel::Warning); + print(tr("[DEBUG] A secret debugging message..."), MessageLevel::Debug); + print(tr("[FATAL] A terrifying fatal error!"), MessageLevel::Fatal); } -void AppearancePage::updateCatPreview() +void AppearanceWidget::updateCatPreview() { QIcon catPackIcon(APPLICATION->themeManager()->getCatPack()); m_ui->catPreview->setIcon(catPackIcon); diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/AppearanceWidget.h similarity index 59% rename from launcher/ui/widgets/ThemeCustomizationWidget.h rename to launcher/ui/widgets/AppearanceWidget.h index d5b160f3f..3bc663676 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/AppearanceWidget.h @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher + * Copyright (C) 2025 TheKodeToad * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify @@ -15,40 +16,46 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + #pragma once -#include -#include "translations/TranslationsModel.h" +#include +#include -enum ThemeFields { NONE = 0b0000, ICONS = 0b0001, WIDGETS = 0b0010, CAT = 0b0100 }; +#include +#include +#include "java/JavaChecker.h" +#include "ui/pages/BasePage.h" + +class QTextCharFormat; +class SettingsObject; namespace Ui { -class ThemeCustomizationWidget; +class AppearanceWidget; } -class ThemeCustomizationWidget : public QWidget { +class AppearanceWidget : public QWidget { Q_OBJECT public: - explicit ThemeCustomizationWidget(QWidget* parent = nullptr); - ~ThemeCustomizationWidget() override; + explicit AppearanceWidget(bool simple, QWidget* parent = 0); + virtual ~AppearanceWidget(); + public: void applySettings(); - void loadSettings(); - void retranslate(); + void retranslateUi(); - private slots: + private: void applyIconTheme(int index); void applyWidgetTheme(int index); void applyCatTheme(int index); - void refresh(); + void loadThemeSettings(); - signals: - int currentIconThemeChanged(int index); - int currentWidgetThemeChanged(int index); - int currentCatChanged(int index); + void updateConsolePreview(); + void updateCatPreview(); - private: - Ui::ThemeCustomizationWidget* ui; + Ui::AppearanceWidget* m_ui; + QTextCharFormat* m_defaultFormat; + bool m_themesOnly; }; diff --git a/launcher/ui/pages/global/AppearancePage.ui b/launcher/ui/widgets/AppearanceWidget.ui similarity index 56% rename from launcher/ui/pages/global/AppearancePage.ui rename to launcher/ui/widgets/AppearanceWidget.ui index 5b159ff15..61e1167f9 100644 --- a/launcher/ui/pages/global/AppearancePage.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -1,7 +1,7 @@ - AppearancePage - + AppearanceWidget + 0 @@ -16,10 +16,7 @@ 0 - - Form - - + @@ -269,214 +266,8 @@ Preview - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::NoFocus - - - - - - - .. - - - true - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - false - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - @@ -502,6 +293,216 @@ + + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::NoFocus + + + + + + + .. + + + true + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAsNeeded + + + false + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + @@ -516,6 +517,7 @@ iconsFolder catPackComboBox catPackFolder + reloadThemesButton consoleFont fontSizeBox catOpacitySlider diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp deleted file mode 100644 index b9412a10a..000000000 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (C) 2024 Tayou - * - * 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 . - */ -#include "ThemeCustomizationWidget.h" -#include "ui_ThemeCustomizationWidget.h" - -#include "Application.h" -#include "DesktopServices.h" -#include "ui/themes/ITheme.h" -#include "ui/themes/ThemeManager.h" - -ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget* parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget) -{ - ui->setupUi(this); - loadSettings(); - ThemeCustomizationWidget::refresh(); - - connect(ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme); - connect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, - &ThemeCustomizationWidget::applyWidgetTheme); - connect(ui->backgroundCatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme); - - connect(ui->iconsFolder, &QPushButton::clicked, this, - [] { DesktopServices::openPath(APPLICATION->themeManager()->getIconThemesFolder().path()); }); - connect(ui->widgetStyleFolder, &QPushButton::clicked, this, - [] { DesktopServices::openPath(APPLICATION->themeManager()->getApplicationThemesFolder().path()); }); - connect(ui->catPackFolder, &QPushButton::clicked, this, - [] { DesktopServices::openPath(APPLICATION->themeManager()->getCatPacksFolder().path()); }); - - connect(ui->refreshButton, &QPushButton::clicked, this, &ThemeCustomizationWidget::refresh); -} - -ThemeCustomizationWidget::~ThemeCustomizationWidget() -{ - delete ui; -} - -void ThemeCustomizationWidget::applyIconTheme(int index) -{ - auto settings = APPLICATION->settings(); - auto originalIconTheme = settings->get("IconTheme").toString(); - auto newIconTheme = ui->iconsComboBox->itemData(index).toString(); - if (originalIconTheme != newIconTheme) { - settings->set("IconTheme", newIconTheme); - APPLICATION->themeManager()->applyCurrentlySelectedTheme(); - } - - emit currentIconThemeChanged(index); -} - -void ThemeCustomizationWidget::applyWidgetTheme(int index) -{ - auto settings = APPLICATION->settings(); - auto originalAppTheme = settings->get("ApplicationTheme").toString(); - auto newAppTheme = ui->widgetStyleComboBox->itemData(index).toString(); - if (originalAppTheme != newAppTheme) { - settings->set("ApplicationTheme", newAppTheme); - APPLICATION->themeManager()->applyCurrentlySelectedTheme(); - } - - emit currentWidgetThemeChanged(index); -} - -void ThemeCustomizationWidget::applyCatTheme(int index) -{ - auto settings = APPLICATION->settings(); - auto originalCat = settings->get("BackgroundCat").toString(); - auto newCat = ui->backgroundCatComboBox->itemData(index).toString(); - if (originalCat != newCat) { - settings->set("BackgroundCat", newCat); - } - - emit currentCatChanged(index); -} - -void ThemeCustomizationWidget::applySettings() -{ - applyIconTheme(ui->iconsComboBox->currentIndex()); - applyWidgetTheme(ui->widgetStyleComboBox->currentIndex()); - applyCatTheme(ui->backgroundCatComboBox->currentIndex()); -} -void ThemeCustomizationWidget::loadSettings() -{ - auto settings = APPLICATION->settings(); - - { - auto currentIconTheme = settings->get("IconTheme").toString(); - auto iconThemes = APPLICATION->themeManager()->getValidIconThemes(); - int idx = 0; - for (auto iconTheme : iconThemes) { - QIcon iconForComboBox = QIcon(iconTheme->path() + "/scalable/settings"); - ui->iconsComboBox->addItem(iconForComboBox, iconTheme->name(), iconTheme->id()); - if (currentIconTheme == iconTheme->id()) { - ui->iconsComboBox->setCurrentIndex(idx); - } - idx++; - } - } - - { - auto currentTheme = settings->get("ApplicationTheme").toString(); - auto themes = APPLICATION->themeManager()->getValidApplicationThemes(); - int idx = 0; - for (auto& theme : themes) { - ui->widgetStyleComboBox->addItem(theme->name(), theme->id()); - if (theme->tooltip() != "") { - int index = ui->widgetStyleComboBox->count() - 1; - ui->widgetStyleComboBox->setItemData(index, theme->tooltip(), Qt::ToolTipRole); - } - if (currentTheme == theme->id()) { - ui->widgetStyleComboBox->setCurrentIndex(idx); - } - idx++; - } - } - - auto cat = settings->get("BackgroundCat").toString(); - for (auto& catFromList : APPLICATION->themeManager()->getValidCatPacks()) { - QIcon catIcon = QIcon(QString("%1").arg(catFromList->path())); - ui->backgroundCatComboBox->addItem(catIcon, catFromList->name(), catFromList->id()); - if (cat == catFromList->id()) { - ui->backgroundCatComboBox->setCurrentIndex(ui->backgroundCatComboBox->count() - 1); - } - } -} - -void ThemeCustomizationWidget::retranslate() -{ - ui->retranslateUi(this); -} - -void ThemeCustomizationWidget::refresh() -{ - applySettings(); - disconnect(ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme); - disconnect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, - &ThemeCustomizationWidget::applyWidgetTheme); - disconnect(ui->backgroundCatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, - &ThemeCustomizationWidget::applyCatTheme); - APPLICATION->themeManager()->refresh(); - ui->iconsComboBox->clear(); - ui->widgetStyleComboBox->clear(); - ui->backgroundCatComboBox->clear(); - loadSettings(); - connect(ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme); - connect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, - &ThemeCustomizationWidget::applyWidgetTheme); - connect(ui->backgroundCatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme); -}; \ No newline at end of file From 8852b5823ba269529a4105504ee54fdd6ee5329a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 23 Mar 2025 13:04:14 +0000 Subject: [PATCH 10/62] Rework tools page Signed-off-by: TheKodeToad --- launcher/tools/JVisualVM.cpp | 4 +- launcher/tools/JVisualVM.h | 2 +- .../ui/pages/global/ExternalToolsPage.cpp | 11 +- launcher/ui/pages/global/ExternalToolsPage.h | 2 +- launcher/ui/pages/global/ExternalToolsPage.ui | 270 +++++++++++------- launcher/ui/pages/global/LauncherPage.ui | 132 ++++----- 6 files changed, 247 insertions(+), 174 deletions(-) diff --git a/launcher/tools/JVisualVM.cpp b/launcher/tools/JVisualVM.cpp index 4da4e1e54..0cae8e37b 100644 --- a/launcher/tools/JVisualVM.cpp +++ b/launcher/tools/JVisualVM.cpp @@ -24,7 +24,7 @@ JVisualVM::JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject* void JVisualVM::profilerStarted() { - emit readyToLaunch(tr("JVisualVM started")); + emit readyToLaunch(tr("VisualVM started")); } void JVisualVM::profilerFinished([[maybe_unused]] int exit, QProcess::ExitStatus status) @@ -82,7 +82,7 @@ bool JVisualVMFactory::check(const QString& path, QString* error) } QFileInfo finfo(path); if (!finfo.isExecutable() || !finfo.fileName().contains("visualvm")) { - *error = QObject::tr("Invalid path to JVisualVM"); + *error = QObject::tr("Invalid path to VisualVM"); return false; } return true; diff --git a/launcher/tools/JVisualVM.h b/launcher/tools/JVisualVM.h index 2828119a1..c152aecdb 100644 --- a/launcher/tools/JVisualVM.h +++ b/launcher/tools/JVisualVM.h @@ -4,7 +4,7 @@ class JVisualVMFactory : public BaseProfilerFactory { public: - QString name() const override { return "JVisualVM"; } + QString name() const override { return "VisualVM"; } void registerSettings(SettingsObjectPtr settings) override; BaseExternalTool* createTool(InstancePtr instance, QObject* parent = 0) override; bool check(QString* error) override; diff --git a/launcher/ui/pages/global/ExternalToolsPage.cpp b/launcher/ui/pages/global/ExternalToolsPage.cpp index 33e9c5388..4110bd5ad 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.cpp +++ b/launcher/ui/pages/global/ExternalToolsPage.cpp @@ -50,7 +50,6 @@ ExternalToolsPage::ExternalToolsPage(QWidget* parent) : QWidget(parent), ui(new Ui::ExternalToolsPage) { ui->setupUi(this); - ui->tabWidget->tabBar()->hide(); ui->jsonEditorTextBox->setClearButtonEnabled(true); @@ -128,13 +127,13 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() QString raw_dir = ui->jvisualvmPathEdit->text(); QString error; do { - raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir); + raw_dir = QFileDialog::getOpenFileName(this, tr("VisualVM Executable"), raw_dir); if (raw_dir.isEmpty()) { break; } QString cooked_dir = FS::NormalizePath(raw_dir); if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) { - QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); + QMessageBox::critical(this, tr("Error"), tr("Error while checking VisualVM install:\n%1").arg(error)); continue; } else { ui->jvisualvmPathEdit->setText(cooked_dir); @@ -146,9 +145,9 @@ void ExternalToolsPage::on_jvisualvmCheckBtn_clicked() { QString error; if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) { - QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); + QMessageBox::critical(this, tr("Error"), tr("Error while checking VisualVM install:\n%1").arg(error)); } else { - QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK")); + QMessageBox::information(this, tr("OK"), tr("VisualVM setup seems to be OK")); } } @@ -187,7 +186,7 @@ void ExternalToolsPage::on_mceditCheckBtn_clicked() void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked() { - QString raw_file = QFileDialog::getOpenFileName(this, tr("JSON Editor"), + QString raw_file = QFileDialog::getOpenFileName(this, tr("Text Editor"), ui->jsonEditorTextBox->text().isEmpty() #if defined(Q_OS_LINUX) ? QString("/usr/bin") diff --git a/launcher/ui/pages/global/ExternalToolsPage.h b/launcher/ui/pages/global/ExternalToolsPage.h index 7248f0c99..377488ccf 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.h +++ b/launcher/ui/pages/global/ExternalToolsPage.h @@ -51,7 +51,7 @@ class ExternalToolsPage : public QWidget, public BasePage { explicit ExternalToolsPage(QWidget* parent = 0); ~ExternalToolsPage(); - QString displayName() const override { return tr("External Tools"); } + QString displayName() const override { return tr("Tools"); } QIcon icon() const override { auto icon = APPLICATION->getThemedIcon("externaltools"); diff --git a/launcher/ui/pages/global/ExternalToolsPage.ui b/launcher/ui/pages/global/ExternalToolsPage.ui index 47c77842a..37eb7de3e 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.ui +++ b/launcher/ui/pages/global/ExternalToolsPage.ui @@ -7,45 +7,48 @@ 0 0 673 - 751 + 823 - - 0 - - - 0 - - - 0 - - - 0 - - - - 0 + + + true - - - Tab 1 - - + + + + 0 + 0 + 653 + 803 + + + - + - J&Profiler + &Editors - + - + + + &Text Editor + + + jsonEditorTextBox + + + + + - + - + Browse @@ -54,70 +57,50 @@ - + - Check + Used to edit component JSON files. - + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + - <html><head/><body><p><a href="https://www.ej-technologies.com/products/jprofiler/overview.html">https://www.ej-technologies.com/products/jprofiler/overview.html</a></p></body></html> + &MCEdit + + + mceditPathEdit - - - - - - - J&VisualVM - - - - - - - - - - - Browse - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="https://visualvm.github.io/">https://visualvm.github.io/</a></p></body></html> - - - - - - - - - - &MCEdit - - + + + + Check + + + @@ -127,17 +110,10 @@ - - - - Check - - - - <html><head/><body><p><a href="https://www.mcedit.net/">https://www.mcedit.net/</a></p></body></html> + <html><head/><body><p><a href="https://www.mcedit.net/">MCEdit Website</a> - Used as world editor in the instance Worlds menu.</p></body></html> @@ -145,28 +121,126 @@ - + - External Editors (leave empty for system default) + &Profilers - - - - - + + - &Text Editor: + Profilers are accessible through the Launch dropdown menu. jsonEditorTextBox - - + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + - Browse + J&Profiler + + + jprofilerPathEdit + + + + + + + + + + + + Check + + + + + + + Browse + + + + + + + + + <html><head/><body><p><a href="https://www.ej-technologies.com/products/jprofiler/overview.html">JProfiler Website</a></p></body></html> + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + + + &VisualVM + + + jvisualvmPathEdit + + + + + + + + + + + + Check + + + + + + + Browse + + + + + + + + + <html><head/><body><p><a href="https://visualvm.github.io/">VisualVM Website</a></p></body></html> @@ -180,8 +254,8 @@ - 20 - 216 + 0 + 0 diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 24678549f..d29ee31be 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -167,46 +167,13 @@ Folders - - + + - &Mods + &Java - modsDirTextBox - - - - - - - - - - &Icons - - - iconsDirTextBox - - - - - - - &Downloads - - - downloadsDirTextBox - - - - - - - &Skins - - - skinsDirTextBox + javaDirTextBox @@ -220,40 +187,84 @@ - - - - - - - - + + - &Java + &Downloads - javaDirTextBox + downloadsDirTextBox + + + + + + + &Icons + + + iconsDirTextBox + + + + + + + + + + Browse - - + + - - + + Browse - - + + + + + + + &Mods + + + modsDirTextBox + + + + + + + Browse + + + + + + + &Skins + + + skinsDirTextBox + + + + + Browse @@ -266,13 +277,6 @@ - - - - Browse - - - @@ -280,12 +284,8 @@ - - - - Browse - - + + From 8732e17db9fefab9a272eb30699f62fea965ebfb Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 23 Mar 2025 13:50:08 +0000 Subject: [PATCH 11/62] Improve appearance icons for simple theme Signed-off-by: TheKodeToad --- .../resources/pe_blue/scalable/appearance.svg | 31 ++++++++---------- .../pe_colored/scalable/appearance.svg | 32 ++++++++----------- .../resources/pe_dark/scalable/appearance.svg | 28 +++++++--------- .../pe_light/scalable/appearance.svg | 30 ++++++++--------- 4 files changed, 52 insertions(+), 69 deletions(-) diff --git a/launcher/resources/pe_blue/scalable/appearance.svg b/launcher/resources/pe_blue/scalable/appearance.svg index 1d49d9d6f..9323ec02d 100644 --- a/launcher/resources/pe_blue/scalable/appearance.svg +++ b/launcher/resources/pe_blue/scalable/appearance.svg @@ -21,11 +21,11 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="8" - inkscape:cx="17.375" - inkscape:cy="18.5" + inkscape:zoom="11.313708" + inkscape:cx="4.9497475" + inkscape:cy="37.388271" inkscape:window-width="1920" - inkscape:window-height="1027" + inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" @@ -54,17 +54,12 @@ height="4" x="1.4899759" y="7.1611009" /> + id="g2657" + transform="rotate(31.454004,7.3789217,28.015625)"> diff --git a/launcher/resources/pe_colored/scalable/appearance.svg b/launcher/resources/pe_colored/scalable/appearance.svg index ac9cc258a..88c1eaf26 100644 --- a/launcher/resources/pe_colored/scalable/appearance.svg +++ b/launcher/resources/pe_colored/scalable/appearance.svg @@ -21,16 +21,17 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="32" - inkscape:cx="7.59375" - inkscape:cy="16.59375" + inkscape:zoom="16" + inkscape:cx="-7.8125" + inkscape:cy="17.6875" inkscape:window-width="1920" - inkscape:window-height="1027" + inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="g7954" - showgrid="false" /> + style="fill:#c1272d;fill-opacity:1;stroke-width:14.5284" + d="M 8.413071,2.4595861 A 2.5,8.0000002 0 0 0 6.3465633,10.337319 2.5,8.0000002 0 0 0 7.4458626,16.960111 C 7.7356137,16.430277 8.2119852,16.01524 8.9151067,15.96976 9.5063364,15.93152 9.9629895,16.336614 10.250228,16.958042 A 2.5,8.0000002 0 0 0 11.346521,10.337343 2.5,8.0000002 0 0 0 8.8459304,2.3382251 2.5,8.0000002 0 0 0 8.413071,2.4595861 Z" /> diff --git a/launcher/resources/pe_dark/scalable/appearance.svg b/launcher/resources/pe_dark/scalable/appearance.svg index b50372fba..24b7283e4 100644 --- a/launcher/resources/pe_dark/scalable/appearance.svg +++ b/launcher/resources/pe_dark/scalable/appearance.svg @@ -22,10 +22,10 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="8" - inkscape:cx="17.375" + inkscape:cx="17.5" inkscape:cy="18.5" inkscape:window-width="1920" - inkscape:window-height="1027" + inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" @@ -53,17 +53,13 @@ height="4" x="1.4899759" y="7.1611009" /> + id="g2657" + transform="rotate(31.454004,7.3789216,28.015625)" + style="fill:#666666;fill-opacity:1"> diff --git a/launcher/resources/pe_light/scalable/appearance.svg b/launcher/resources/pe_light/scalable/appearance.svg index 4f000f452..61b2f3422 100644 --- a/launcher/resources/pe_light/scalable/appearance.svg +++ b/launcher/resources/pe_light/scalable/appearance.svg @@ -21,11 +21,11 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="8" - inkscape:cx="17.375" - inkscape:cy="18.5" + inkscape:zoom="16" + inkscape:cx="16.875" + inkscape:cy="15.4375" inkscape:window-width="1920" - inkscape:window-height="1027" + inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" @@ -54,17 +54,13 @@ height="4" x="1.4899759" y="7.1611009" /> + style="fill:#ffffff;fill-opacity:1;stroke-width:14.5284" + d="M 8.413071,2.4595861 A 2.5,8.0000002 0 0 0 6.3465633,10.337319 2.5,8.0000002 0 0 0 7.4458626,16.960111 C 7.7356137,16.430277 8.2119852,16.01524 8.9151067,15.96976 9.5063364,15.93152 9.9629895,16.336614 10.250228,16.958042 A 2.5,8.0000002 0 0 0 11.346521,10.337343 2.5,8.0000002 0 0 0 8.8459304,2.3382251 2.5,8.0000002 0 0 0 8.413071,2.4595861 Z" /> From adf2ed0849094761a33aa10ff45f616550968067 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 23 Mar 2025 15:22:17 +0000 Subject: [PATCH 12/62] Only fire apply event when settings are actually applied Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 +- launcher/Application.h | 2 +- launcher/ui/InstanceWindow.cpp | 2 +- launcher/ui/MainWindow.cpp | 2 +- launcher/ui/pagedialog/PageDialog.cpp | 20 ++++++++++++------- launcher/ui/pagedialog/PageDialog.h | 10 ++++++++-- .../ui/pages/instance/InstanceSettingsPage.h | 2 +- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index b1cad5ad4..0f7d85b6b 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1564,9 +1564,9 @@ void Application::ShowGlobalSettings(class QWidget* parent, QString open_page) { SettingsObject::Lock lock(APPLICATION->settings()); PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); + connect(&dlg, &PageDialog::applied, this, &Application::globalSettingsApplied); dlg.exec(); } - emit globalSettingsClosed(); } MainWindow* Application::showMainWindow(bool minimized) diff --git a/launcher/Application.h b/launcher/Application.h index 12f41509c..63432f7e5 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -197,7 +197,7 @@ class Application : public QApplication { signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); - void globalSettingsClosed(); + void globalSettingsApplied(); int currentCatChanged(int index); void oauthReplyRecieved(QVariantMap); diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index bf83a56c9..2f156e125 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -111,7 +111,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget* parent) : QMainWin m_container->addButtons(horizontalLayout); connect(m_instance.get(), &BaseInstance::profilerChanged, this, &InstanceWindow::updateButtons); - connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceWindow::updateButtons); + connect(APPLICATION, &Application::globalSettingsApplied, this, &InstanceWindow::updateButtons); } // restore window state diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index a9473ac15..8b41f838c 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -351,7 +351,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi connect(APPLICATION->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); // When the global settings page closes, we want to know about it and update our state - connect(APPLICATION, &Application::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); + connect(APPLICATION, &Application::globalSettingsApplied, this, &MainWindow::globalSettingsClosed); m_statusLeft = new QLabel(tr("No instance selected"), this); m_statusCenter = new QLabel(tr("Total playtime: 0s"), this); diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 275908efa..bfa9ebdb0 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -43,20 +43,26 @@ PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidge buttons->setContentsMargins(6, 0, 6, 0); m_container->addButtons(buttons); - connect(buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &PageDialog::applyAndClose); + connect(buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &PageDialog::accept); connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &PageDialog::reject); connect(buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help); + connect(this, &QDialog::accepted, this, &PageDialog::onAccepted); + connect(this, &QDialog::rejected, this, &PageDialog::storeGeometry); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } -void PageDialog::applyAndClose() +void PageDialog::onAccepted() { - qDebug() << "Paged dialog apply and close requested"; + qDebug() << "Paged dialog accepted"; if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; - APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); - qDebug() << "Paged dialog geometry saved"; - close(); + emit applied(); } - +} + +void PageDialog::storeGeometry() +{ + APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); + qDebug() << "Paged dialog geometry saved"; } diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index 337cfd3a3..d4af862f3 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -25,8 +25,14 @@ class PageDialog : public QDialog { explicit PageDialog(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0); virtual ~PageDialog() {} - private: - void applyAndClose(); + signals: + void applied(); + + private slots: + void onAccepted(); + void storeGeometry(); + + private: PageContainer* m_container; }; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index fa1dce3dc..2549c1084 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -48,7 +48,7 @@ class InstanceSettingsPage : public MinecraftSettingsWidget, public BasePage { explicit InstanceSettingsPage(MinecraftInstancePtr instance, QWidget* parent = nullptr) : MinecraftSettingsWidget(std::move(instance), parent) { connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::saveSettings); - connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); + connect(APPLICATION, &Application::globalSettingsApplied, this, &InstanceSettingsPage::loadSettings); } ~InstanceSettingsPage() override {} QString displayName() const override { return tr("Settings"); } From 3922136f6d7036144cf493899c4eaecee53c9d45 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 00:29:07 +0000 Subject: [PATCH 13/62] Rework Minecraft and Java settings Signed-off-by: TheKodeToad --- launcher/Application.cpp | 1 + launcher/JavaCommon.cpp | 2 +- launcher/ui/pages/global/JavaPage.ui | 49 +- launcher/ui/widgets/AppearanceWidget.ui | 5 +- launcher/ui/widgets/EnvironmentVariables.ui | 76 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 99 ++- launcher/ui/widgets/JavaSettingsWidget.h | 5 +- launcher/ui/widgets/JavaSettingsWidget.ui | 652 ++++++++++++++---- .../ui/widgets/MinecraftSettingsWidget.ui | 198 ++++-- 9 files changed, 776 insertions(+), 311 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 0f7d85b6b..054d27f8a 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -665,6 +665,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("AutomaticJavaSwitch", defaultEnableAutoJava); m_settings->registerSetting("AutomaticJavaDownload", defaultEnableAutoJava); m_settings->registerSetting("UserAskedAboutAutomaticJavaDownload", false); + m_settings->registerSetting("AdvancedJavaMemoryControl", false); // Legacy settings m_settings->registerSetting("OnlineFixes", false); diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index 188edb943..fc78f5f26 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -93,7 +93,7 @@ void JavaCommon::javaBinaryWasBad(QWidget* parent, const JavaChecker::Result& re { QString text; text += QObject::tr( - "The specified Java binary didn't work.
You should use the auto-detect feature, " + "The specified Java binary didn't work.
You should press 'Detect', " "or set the path to the Java executable.
"); CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show(); } diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index a4b2ac203..25c641cb5 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -32,7 +32,7 @@ - 0 + 1 @@ -50,7 +50,7 @@ 0 0 535 - 610 + 606 @@ -73,19 +73,9 @@ Downloaded Java Versions - + - - - - 0 - 0 - - - - - - + @@ -101,14 +91,14 @@ - + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 @@ -122,22 +112,19 @@ + + + + + 0 + 0 + + + + - - - - Qt::Vertical - - - - 20 - 40 - - - -
diff --git a/launcher/ui/widgets/AppearanceWidget.ui b/launcher/ui/widgets/AppearanceWidget.ui index 61e1167f9..d646cb9e0 100644 --- a/launcher/ui/widgets/AppearanceWidget.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -239,6 +239,9 @@
+ + false + Transparent @@ -247,7 +250,7 @@ - true + false Opaque diff --git a/launcher/ui/widgets/EnvironmentVariables.ui b/launcher/ui/widgets/EnvironmentVariables.ui index ded5b2ded..828626d12 100644 --- a/launcher/ui/widgets/EnvironmentVariables.ui +++ b/launcher/ui/widgets/EnvironmentVariables.ui @@ -35,6 +35,44 @@ true + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Clear + + + + + @@ -67,44 +105,6 @@ - - - - - - &Add - - - - - - - &Remove - - - - - - - &Clear - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index a255168e9..200d81db8 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -53,6 +53,11 @@ #include "ui_JavaSettingsWidget.h" +static QString formatGiBLabel(int value) +{ + return QObject::tr("%1 GiB").arg(value / 1024.0, 0, 'f', 1); +} + JavaSettingsWidget::JavaSettingsWidget(InstancePtr instance, QWidget* parent) : QWidget(parent), m_instance(std::move(instance)), m_ui(new Ui::JavaSettingsWidget) { @@ -101,11 +106,50 @@ JavaSettingsWidget::JavaSettingsWidget(InstancePtr instance, QWidget* parent) connect(m_ui->javaDetectBtn, &QPushButton::clicked, this, &JavaSettingsWidget::onJavaAutodetect); connect(m_ui->javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::onJavaBrowse); - connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::updateThresholds); - connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::updateThresholds); + connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), m_ui->minMemSlider, [this](int value) { + m_ui->minMemSlider->blockSignals(true); + m_ui->minMemSlider->setValue(value); + m_ui->minMemSlider->blockSignals(false); + }); + connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), m_ui->maxMemSlider, [this](int value) { + m_ui->maxMemSlider->blockSignals(true); + m_ui->maxMemSlider->setValue(value); + m_ui->maxMemSlider->blockSignals(false); + }); + + connect(m_ui->minMemSlider, &QAbstractSlider::valueChanged, m_ui->minMemSpinBox, QOverload::of(&QSpinBox::setValue)); + connect(m_ui->maxMemSlider, &QAbstractSlider::valueChanged, m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::setValue)); + + connect(m_ui->minMemSpinBox, &QAbstractSpinBox::editingFinished, this, &JavaSettingsWidget::finishAdjustingMinMemory); + connect(m_ui->maxMemSpinBox, &QAbstractSpinBox::editingFinished, this, &JavaSettingsWidget::finishAdjustingMaxMemory); + connect(m_ui->minMemSlider, &QAbstractSlider::valueChanged, this, &JavaSettingsWidget::finishAdjustingMinMemory); + connect(m_ui->maxMemSlider, &QAbstractSlider::valueChanged, this, &JavaSettingsWidget::finishAdjustingMaxMemory); + + connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::onMemoryChange); + connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::onMemoryChange); + + int maxSystemMemory = (Sys::getSystemRam() / Sys::mebibyte) - 1; + m_ui->minMemSlider->setMaximum(maxSystemMemory - 1); + m_ui->maxMemSlider->setMaximum(maxSystemMemory - 1); + m_ui->minMemMaxValueHint->setText(formatGiBLabel(maxSystemMemory - 1)); + m_ui->maxMemMaxValueHint->setText(formatGiBLabel(maxSystemMemory - 1)); + + SettingsObjectPtr settings = APPLICATION->settings(); + + enableAdvancedMemoryControl(settings->get("AdvancedJavaMemoryControl").toBool()); + + connect(m_ui->memorySimpleButton, &QPushButton::clicked, this, [this, settings] () { + enableAdvancedMemoryControl(false); + settings->set("AdvancedJavaMemoryControl", false); + }); + + connect(m_ui->memoryAdvancedButton, &QPushButton::clicked, this, [this, settings] () { + enableAdvancedMemoryControl(true); + settings->set("AdvancedJavaMemoryControl", true); + }); loadSettings(); - updateThresholds(); + onMemoryChange(); } JavaSettingsWidget::~JavaSettingsWidget() @@ -283,32 +327,43 @@ void JavaSettingsWidget::onJavaAutodetect() } } } -void JavaSettingsWidget::updateThresholds() + +void JavaSettingsWidget::onMemoryChange() { auto sysMiB = Sys::getSystemRam() / Sys::mebibyte; unsigned int maxMem = m_ui->maxMemSpinBox->value(); - unsigned int minMem = m_ui->minMemSpinBox->value(); - - QString iconName; if (maxMem >= sysMiB) { - iconName = "status-bad"; - m_ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation exceeds your system memory capacity.")); + m_ui->labelMaxMemNotice->setText(QString("%1").arg(tr("Your maximum memory allocation exceeds your system memory capacity."))); + m_ui->labelMaxMemNotice->show(); } else if (maxMem > (sysMiB * 0.9)) { - iconName = "status-yellow"; - m_ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity.")); - } else if (maxMem < minMem) { - iconName = "status-yellow"; - m_ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value")); + // TODO: where is this colour from + m_ui->labelMaxMemNotice->setText(QString("%1") + .arg(tr("Your maximum memory allocation is close to your system memory capacity."))); + m_ui->labelMaxMemNotice->show(); } else { - iconName = "status-good"; - m_ui->labelMaxMemIcon->setToolTip(""); + m_ui->labelMaxMemNotice->hide(); } - { - auto height = m_ui->labelMaxMemIcon->fontInfo().pixelSize(); - QIcon icon = APPLICATION->getThemedIcon(iconName); - QPixmap pix = icon.pixmap(height, height); - m_ui->labelMaxMemIcon->setPixmap(pix); - } + m_ui->minMemGBLabel->setText(formatGiBLabel(m_ui->minMemSlider->value())); + m_ui->maxMemGBLabel->setText(formatGiBLabel(m_ui->maxMemSlider->value())); +} + +void JavaSettingsWidget::finishAdjustingMinMemory() +{ + if (m_ui->minMemSpinBox->value() > m_ui->maxMemSpinBox->value()) + m_ui->maxMemSpinBox->setValue(m_ui->minMemSpinBox->value()); +} + +void JavaSettingsWidget::finishAdjustingMaxMemory() +{ + if (m_ui->maxMemSpinBox->value() < m_ui->minMemSpinBox->value()) + m_ui->minMemSpinBox->setValue(m_ui->maxMemSpinBox->value()); +} + +void JavaSettingsWidget::enableAdvancedMemoryControl(bool enabled) { + m_ui->memorySimpleButton->setChecked(!enabled); + m_ui->memoryAdvancedButton->setChecked(enabled); + m_ui->memorySimple->setVisible(!enabled); + m_ui->memoryAdvanced->setVisible(enabled); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 21a71fb8b..ed38d63f8 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -59,7 +59,10 @@ class JavaSettingsWidget : public QWidget { void onJavaBrowse(); void onJavaAutodetect(); void onJavaTest(); - void updateThresholds(); + void onMemoryChange(); + void finishAdjustingMinMemory(); + void finishAdjustingMaxMemory(); + void enableAdvancedMemoryControl(bool enabled); private: InstancePtr m_instance; diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 15ce88f0c..0e44980bf 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -7,13 +7,56 @@ 0 0 500 - 600 + 1123 Form + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Test S&ettings + + + + + + + Open Java &Downloader + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + @@ -29,6 +72,43 @@ false + + + + + + + + + &Detect + + + + + + + + 0 + 0 + + + + &Browse + + + + + + + + + If enabled, the launcher will not check if an instance is compatible with the selected Java version. + + + Skip Java compatibility checks + + + @@ -36,45 +116,6 @@ - - - - - - - - - Browse - - - - - - - - - - - Download Java - - - - - - - Auto-detect... - - - - - - - Test - - - - - @@ -95,13 +136,13 @@ - - - - If enabled, the launcher will not check if an instance is compatible with the selected Java version. - + + - Skip Java compatibility checks + Java &Executable + + + javaPathTextBox @@ -122,104 +163,422 @@ false - - - + + + + + + + Simple + + + true + + + false + + + + + + + Advanced + + + true + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + M&inimum Memory Usage + + + minMemSpinBox + + + + + + + 0 GiB + + + + + + + 8 + + + 8192 + + + 512 + + + 512 + + + true + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1024 + + + + + + + + + false + + + 0 GiB + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + 8 GiB + + + + + + + + + M&aximum Memory Usage + + + maxMemSpinBox + + + + + + + 0 GiB + + + + + + + 8 + + + 8192 + + + 512 + + + 512 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1024 + + + + + + + + + false + + + 0 GiB + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + 8 GiB + + + + + + + + + + + + + + + Minimum Memory Allocation + + + + + + + 0 + + + + + -Xm&s= + + + minMemSpinBox + + + + + + + + 0 + 0 + + + + The amount of memory Minecraft is started with. + + + M + + + 8 + + + 1048576 + + + 128 + + + 256 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Maximum Memory Allocation + + + + + + + 0 + + + + + -Xm&x= + + + maxMemSpinBox + + + + + + + + 0 + 0 + + + + The maximum amount of memory Minecraft is allowed to use. + + + M + + + 8 + + + 1048576 + + + 128 + + + 1024 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + PermGen Size + + + + + + + 0 + + + + + -XX:&PermSize= + + + permGenSpinBox + + + + + + + + 0 + 0 + + + + The amount of memory available to store loaded Java classes. + + + M + + + 4 + + + 999999999 + + + 8 + + + 64 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + - PermGen (Java 7 and earlier): - - - - - - - Minimum memory allocation: - - - - - - - The amount of memory available to store loaded Java classes. - - - MiB - - - 4 - - - 999999999 - - - 8 - - - 64 - - - - - - - Maximum memory allocation: - - - - - - - - - - Qt::AlignCenter - - - maxMemSpinBox - - - - - - - The maximum amount of memory Minecraft is allowed to use. - - - MiB - - - 8 - - - 1048576 - - - 128 - - - 1024 - - - - - - - The amount of memory Minecraft is started with. - - - MiB - - - 8 - - - 1048576 - - - 128 - - - 256 + Maximum Memory Notice @@ -251,17 +610,10 @@ javaPathTextBox - javaBrowseBtn - javaDownloadBtn - javaDetectBtn - javaTestBtn skipCompatibilityCheckBox skipWizardCheckBox autodetectJavaCheckBox autodownloadJavaCheckBox - minMemSpinBox - maxMemSpinBox - permGenSpinBox jvmArgsTextBox diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index daa065ac8..34fa9af80 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -51,9 +51,6 @@ 0 - - Qt::ScrollBarAlwaysOff - true @@ -61,9 +58,9 @@ 0 - -253 + 0 610 - 550 + 610 @@ -100,23 +97,73 @@ - - - - - Window height: + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + + + &Window Size + + + windowWidthSpinBox + + + + + + + + + + 0 + 0 + + + + + + + 1 + + + 65536 + + + 480 - - + + - Window width: + × - + + + + 0 + 0 + + + + + 1 @@ -131,19 +178,26 @@ - - - - 1 - - - 65536 - - - 480 + + + + pixels + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -298,7 +352,7 @@ 0 0 624 - 297 + 291 @@ -313,9 +367,6 @@ - - Qt::ScrollBarAlwaysOff - true @@ -323,9 +374,9 @@ 0 - -101 + 0 610 - 398 + 501 @@ -369,7 +420,7 @@ false - + Use system installation of OpenAL @@ -386,6 +437,13 @@ + + + + false + + + @@ -393,14 +451,7 @@ - - - - false - - - - + &OpenAL library path @@ -410,8 +461,24 @@ - - + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + false @@ -513,7 +580,7 @@ 0 0 624 - 297 + 291 @@ -530,24 +597,27 @@ - - - - - - 0 - 0 - - - - Account: - - - - - - - + + + + 0 + 0 + + + + Account + + + + + + + + 0 + 0 + + + @@ -567,7 +637,7 @@ - Server address: + Server address @@ -647,10 +717,7 @@ openGlobalSettingsButton settingsTabs - scrollArea maximizedCheckBox - windowWidthSpinBox - windowHeightSpinBox showGameTime recordGameTime showGlobalGameTime @@ -664,9 +731,7 @@ scrollArea_2 onlineFixes useNativeGLFWCheck - lineEditGLFWPath useNativeOpenALCheck - lineEditOpenALPath perfomanceGroupBox enableFeralGamemodeCheck enableMangoHud @@ -674,7 +739,6 @@ useZink scrollArea_3 instanceAccountGroupBox - instanceAccountSelector serverJoinGroupBox serverJoinAddressButton serverJoinAddress From 2ab08f01b13a2467161a8fe268cefd75fa602d9a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 00:30:23 +0000 Subject: [PATCH 14/62] Merge mods & modpack settings Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index d29ee31be..64609be99 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -29,9 +29,9 @@ 0 - 0 - 563 - 1336 + -329 + 566 + 1296 @@ -293,7 +293,7 @@ - Mods + Mods and Modpacks @@ -346,15 +346,6 @@ - - - - - - - Modpacks - - From ad8818a13491d1ac12d2d5920c7123881f9d1f83 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 00:36:03 +0000 Subject: [PATCH 15/62] Improve proxy page Signed-off-by: TheKodeToad --- launcher/ui/pages/global/ProxyPage.ui | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 91ba46b3d..3f794ea61 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -54,14 +54,14 @@ Type - + Uses your system's default proxy settings. - &Default + S&ystem Settings proxyGroup @@ -142,6 +142,16 @@ + + + + Note: Proxy username and password are stored in plain text inside the launcher's configuration file! + + + true + + + @@ -152,16 +162,6 @@ - - - - &Password: - - - proxyPassEdit - - - @@ -169,13 +169,13 @@ - - + + - Note: Proxy username and password are stored in plain text inside the launcher's configuration file! + &Password: - - true + + proxyPassEdit From 0434cc648a79a62f583fea8df9c8ce0f06991f58 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 00:36:44 +0000 Subject: [PATCH 16/62] Rearrange settings categories Signed-off-by: TheKodeToad --- launcher/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 054d27f8a..3c12cfe0d 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -800,14 +800,14 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) { m_globalSettingsProvider = std::make_shared(tr("Settings")); m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); } PixmapCache::setInstance(new PixmapCache(this)); From 72b90cf7de504478b7170ac73b4727055a9c14f9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 01:07:40 +0000 Subject: [PATCH 17/62] gay bowser Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 3c12cfe0d..88a613040 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -57,6 +57,7 @@ #include "ui/instanceview/AccessibleInstanceView.h" #include "ui/pages/BasePageProvider.h" +#include "ui/pages/global/AppearancePage.h" #include "ui/pages/global/APIPage.h" #include "ui/pages/global/AccountListPage.h" #include "ui/pages/global/ExternalToolsPage.h" @@ -137,7 +138,6 @@ #if defined(Q_OS_LINUX) #include -#include #endif #if defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) From c5e766512e0b60041c02c7fb47468e808bf95913 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 01:21:52 +0000 Subject: [PATCH 18/62] Improve update interval setting Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 64609be99..b358765a3 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -29,7 +29,7 @@ 0 - -329 + 0 566 1296 @@ -132,7 +132,7 @@ - Update checking interval + How Often? @@ -145,10 +145,16 @@ - Set it to 0 to only check on launch + Set to 0 to only check on launch + + + On Launch - h + hours + + + Every 0 From 0768623e1edbb4d67e42b22c5b462c9c890fad6b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 01:33:23 +0000 Subject: [PATCH 19/62] Select General tab by default on Java page Signed-off-by: TheKodeToad --- launcher/ui/pages/global/JavaPage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 25c641cb5..bc5e9523f 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -32,7 +32,7 @@ - 1 + 0 From 26f9850462ca88a90fe7c0e9c82e2f78f5e681cd Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 01:48:15 +0000 Subject: [PATCH 20/62] fix memory leak Signed-off-by: TheKodeToad --- launcher/ui/widgets/AppearanceWidget.cpp | 6 +++--- launcher/ui/widgets/AppearanceWidget.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher/ui/widgets/AppearanceWidget.cpp b/launcher/ui/widgets/AppearanceWidget.cpp index f9475cbbd..731b72727 100644 --- a/launcher/ui/widgets/AppearanceWidget.cpp +++ b/launcher/ui/widgets/AppearanceWidget.cpp @@ -50,7 +50,7 @@ AppearanceWidget::AppearanceWidget(bool themesOnly, QWidget* parent) m_ui->catPreview->setGraphicsEffect(new QGraphicsOpacityEffect(this)); - m_defaultFormat = new QTextCharFormat(m_ui->consolePreview->currentCharFormat()); + m_defaultFormat = QTextCharFormat(m_ui->consolePreview->currentCharFormat()); if (themesOnly) { m_ui->catPackLabel->hide(); @@ -224,10 +224,10 @@ void AppearanceWidget::updateConsolePreview() int fontSize = m_ui->fontSizeBox->value(); QString fontFamily = m_ui->consoleFont->currentFont().family(); m_ui->consolePreview->clear(); - m_defaultFormat->setFont(QFont(fontFamily, fontSize)); + m_defaultFormat.setFont(QFont(fontFamily, fontSize)); auto print = [this, colors](const QString& message, MessageLevel::Enum level) { - QTextCharFormat format(*m_defaultFormat); + QTextCharFormat format(m_defaultFormat); QColor bg = colors.background.value(level); QColor fg = colors.foreground.value(level); diff --git a/launcher/ui/widgets/AppearanceWidget.h b/launcher/ui/widgets/AppearanceWidget.h index 3bc663676..1fc89af3a 100644 --- a/launcher/ui/widgets/AppearanceWidget.h +++ b/launcher/ui/widgets/AppearanceWidget.h @@ -24,6 +24,7 @@ #include #include +#include #include "java/JavaChecker.h" #include "ui/pages/BasePage.h" @@ -56,6 +57,6 @@ class AppearanceWidget : public QWidget { void updateCatPreview(); Ui::AppearanceWidget* m_ui; - QTextCharFormat* m_defaultFormat; + QTextCharFormat m_defaultFormat; bool m_themesOnly; }; From e1e0a3d887bff6f85051c005e1d182b459176860 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 01:49:43 +0000 Subject: [PATCH 21/62] Remove tabs from proxy page Signed-off-by: TheKodeToad --- launcher/ui/pages/global/ProxyPage.cpp | 1 - launcher/ui/pages/global/ProxyPage.ui | 335 ++++++++++++------------- 2 files changed, 156 insertions(+), 180 deletions(-) diff --git a/launcher/ui/pages/global/ProxyPage.cpp b/launcher/ui/pages/global/ProxyPage.cpp index 9caffcb37..979f07c6a 100644 --- a/launcher/ui/pages/global/ProxyPage.cpp +++ b/launcher/ui/pages/global/ProxyPage.cpp @@ -46,7 +46,6 @@ ProxyPage::ProxyPage(QWidget* parent) : QWidget(parent), ui(new Ui::ProxyPage) { ui->setupUi(this); - ui->tabWidget->tabBar()->hide(); loadSettings(); updateCheckboxStuff(); diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 3f794ea61..830ae1ac8 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -17,188 +17,165 @@ - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - This only applies to the launcher. Minecraft does not accept proxy settings. - - - Qt::AlignCenter - - - true - - - - - - - Type - - - - - - Uses your system's default proxy settings. - - - S&ystem Settings - - - proxyGroup - - - - - - - &None - - - proxyGroup - - - - - - - &SOCKS5 - - - proxyGroup - - - - - - - &HTTP - - - proxyGroup - - - - - - - - - - &Address and Port - - - - - - 127.0.0.1 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::PlusMinus - - - 65535 - - - 8080 - - - - - - - - - - Authentication - - - - - - - - - Note: Proxy username and password are stored in plain text inside the launcher's configuration file! - - - true - - - - - - - &Username: - - - proxyUserEdit - - - - - - - QLineEdit::Password - - - - - - - &Password: - - - proxyPassEdit - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + + This only applies to the launcher. Minecraft does not accept proxy settings. + + + Qt::AlignCenter + + + true + + + + + Type + + + + + + Uses your system's default proxy settings. + + + S&ystem Settings + + + proxyGroup + + + + + + + &None + + + proxyGroup + + + + + + + &SOCKS5 + + + proxyGroup + + + + + + + &HTTP + + + proxyGroup + + + + + + + + + + &Address and Port + + + + + + 127.0.0.1 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + QAbstractSpinBox::PlusMinus + + + 65535 + + + 8080 + + + + + + + + + + Authentication + + + + + + + + + Note: Proxy username and password are stored in plain text inside the launcher's configuration file! + + + true + + + + + + + &Username: + + + proxyUserEdit + + + + + + + QLineEdit::Password + + + + + + + &Password: + + + proxyPassEdit + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + From 4e6bfde7239f83016c9c3f88e7c6991c267fc26b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 11:59:29 +0000 Subject: [PATCH 22/62] Revert sliders Signed-off-by: TheKodeToad --- launcher/Application.cpp | 1 - launcher/ui/pages/global/JavaPage.cpp | 2 +- launcher/ui/widgets/JavaSettingsWidget.cpp | 84 +--- launcher/ui/widgets/JavaSettingsWidget.h | 7 +- launcher/ui/widgets/JavaSettingsWidget.ui | 522 +++++---------------- 5 files changed, 129 insertions(+), 487 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 88a613040..ecd606f43 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -665,7 +665,6 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("AutomaticJavaSwitch", defaultEnableAutoJava); m_settings->registerSetting("AutomaticJavaDownload", defaultEnableAutoJava); m_settings->registerSetting("UserAskedAboutAutomaticJavaDownload", false); - m_settings->registerSetting("AdvancedJavaMemoryControl", false); // Legacy settings m_settings->registerSetting("OnlineFixes", false); diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index b99d0c63e..6a44c9290 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -62,7 +62,7 @@ JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage) { ui->setupUi(this); - + if (BuildConfig.JAVA_DOWNLOADER_ENABLED) { ui->managedJavaList->initialize(new JavaInstallList(this, true)); ui->managedJavaList->setResizeOn(2); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 200d81db8..bd48f3faa 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -53,11 +53,6 @@ #include "ui_JavaSettingsWidget.h" -static QString formatGiBLabel(int value) -{ - return QObject::tr("%1 GiB").arg(value / 1024.0, 0, 'f', 1); -} - JavaSettingsWidget::JavaSettingsWidget(InstancePtr instance, QWidget* parent) : QWidget(parent), m_instance(std::move(instance)), m_ui(new Ui::JavaSettingsWidget) { @@ -106,50 +101,11 @@ JavaSettingsWidget::JavaSettingsWidget(InstancePtr instance, QWidget* parent) connect(m_ui->javaDetectBtn, &QPushButton::clicked, this, &JavaSettingsWidget::onJavaAutodetect); connect(m_ui->javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::onJavaBrowse); - connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), m_ui->minMemSlider, [this](int value) { - m_ui->minMemSlider->blockSignals(true); - m_ui->minMemSlider->setValue(value); - m_ui->minMemSlider->blockSignals(false); - }); - connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), m_ui->maxMemSlider, [this](int value) { - m_ui->maxMemSlider->blockSignals(true); - m_ui->maxMemSlider->setValue(value); - m_ui->maxMemSlider->blockSignals(false); - }); - - connect(m_ui->minMemSlider, &QAbstractSlider::valueChanged, m_ui->minMemSpinBox, QOverload::of(&QSpinBox::setValue)); - connect(m_ui->maxMemSlider, &QAbstractSlider::valueChanged, m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::setValue)); - - connect(m_ui->minMemSpinBox, &QAbstractSpinBox::editingFinished, this, &JavaSettingsWidget::finishAdjustingMinMemory); - connect(m_ui->maxMemSpinBox, &QAbstractSpinBox::editingFinished, this, &JavaSettingsWidget::finishAdjustingMaxMemory); - connect(m_ui->minMemSlider, &QAbstractSlider::valueChanged, this, &JavaSettingsWidget::finishAdjustingMinMemory); - connect(m_ui->maxMemSlider, &QAbstractSlider::valueChanged, this, &JavaSettingsWidget::finishAdjustingMaxMemory); - - connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::onMemoryChange); - connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::onMemoryChange); - - int maxSystemMemory = (Sys::getSystemRam() / Sys::mebibyte) - 1; - m_ui->minMemSlider->setMaximum(maxSystemMemory - 1); - m_ui->maxMemSlider->setMaximum(maxSystemMemory - 1); - m_ui->minMemMaxValueHint->setText(formatGiBLabel(maxSystemMemory - 1)); - m_ui->maxMemMaxValueHint->setText(formatGiBLabel(maxSystemMemory - 1)); - - SettingsObjectPtr settings = APPLICATION->settings(); - - enableAdvancedMemoryControl(settings->get("AdvancedJavaMemoryControl").toBool()); - - connect(m_ui->memorySimpleButton, &QPushButton::clicked, this, [this, settings] () { - enableAdvancedMemoryControl(false); - settings->set("AdvancedJavaMemoryControl", false); - }); - - connect(m_ui->memoryAdvancedButton, &QPushButton::clicked, this, [this, settings] () { - enableAdvancedMemoryControl(true); - settings->set("AdvancedJavaMemoryControl", true); - }); + connect(m_ui->maxMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::updateThresholds); + connect(m_ui->minMemSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &JavaSettingsWidget::updateThresholds); loadSettings(); - onMemoryChange(); + updateThresholds(); } JavaSettingsWidget::~JavaSettingsWidget() @@ -327,43 +283,23 @@ void JavaSettingsWidget::onJavaAutodetect() } } } - -void JavaSettingsWidget::onMemoryChange() +void JavaSettingsWidget::updateThresholds() { auto sysMiB = Sys::getSystemRam() / Sys::mebibyte; unsigned int maxMem = m_ui->maxMemSpinBox->value(); + unsigned int minMem = m_ui->minMemSpinBox->value(); + + const QString warningColour(QStringLiteral("%1")); if (maxMem >= sysMiB) { m_ui->labelMaxMemNotice->setText(QString("%1").arg(tr("Your maximum memory allocation exceeds your system memory capacity."))); m_ui->labelMaxMemNotice->show(); } else if (maxMem > (sysMiB * 0.9)) { - // TODO: where is this colour from - m_ui->labelMaxMemNotice->setText(QString("%1") - .arg(tr("Your maximum memory allocation is close to your system memory capacity."))); + m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is close to your system memory capacity."))); m_ui->labelMaxMemNotice->show(); + } else if (maxMem < minMem) { + m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is below the minimum memory allocation."))) } else { m_ui->labelMaxMemNotice->hide(); } - - m_ui->minMemGBLabel->setText(formatGiBLabel(m_ui->minMemSlider->value())); - m_ui->maxMemGBLabel->setText(formatGiBLabel(m_ui->maxMemSlider->value())); -} - -void JavaSettingsWidget::finishAdjustingMinMemory() -{ - if (m_ui->minMemSpinBox->value() > m_ui->maxMemSpinBox->value()) - m_ui->maxMemSpinBox->setValue(m_ui->minMemSpinBox->value()); -} - -void JavaSettingsWidget::finishAdjustingMaxMemory() -{ - if (m_ui->maxMemSpinBox->value() < m_ui->minMemSpinBox->value()) - m_ui->minMemSpinBox->setValue(m_ui->maxMemSpinBox->value()); -} - -void JavaSettingsWidget::enableAdvancedMemoryControl(bool enabled) { - m_ui->memorySimpleButton->setChecked(!enabled); - m_ui->memoryAdvancedButton->setChecked(enabled); - m_ui->memorySimple->setVisible(!enabled); - m_ui->memoryAdvanced->setVisible(enabled); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index ed38d63f8..85266bc2b 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -59,13 +59,10 @@ class JavaSettingsWidget : public QWidget { void onJavaBrowse(); void onJavaAutodetect(); void onJavaTest(); - void onMemoryChange(); - void finishAdjustingMinMemory(); - void finishAdjustingMaxMemory(); - void enableAdvancedMemoryControl(bool enabled); + void updateThresholds(); private: InstancePtr m_instance; Ui::JavaSettingsWidget* m_ui; unique_qobject_ptr m_checker; -}; +}; \ No newline at end of file diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 0e44980bf..5cc894b8e 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -165,420 +165,123 @@ - - - - - Simple - - - true - - - false - - - - - - - Advanced - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - M&inimum Memory Usage - - - minMemSpinBox - - - - - - - 0 GiB - - - - - - - 8 - - - 8192 - - - 512 - - - 512 - - - true - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 1024 - - - - - - - - - false - - - 0 GiB - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - 8 GiB - - - - - - - - - M&aximum Memory Usage - - - maxMemSpinBox - - - - - - - 0 GiB - - - - - - - 8 - - - 8192 - - - 512 - - - 512 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 1024 - - - - - - - - - false - - - 0 GiB - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - 8 GiB - - - - - - + + + M&inimum Memory Usage (-Xms) + + + minMemSpinBox + - - - - - - Minimum Memory Allocation - - - - - - - 0 - - - - - -Xm&s= - - - minMemSpinBox - - - - - - - - 0 - 0 - - - - The amount of memory Minecraft is started with. - - - M - - - 8 - - - 1048576 - - - 128 - - - 256 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Maximum Memory Allocation - - - - - - - 0 - - - - - -Xm&x= - - - maxMemSpinBox - - - - - - - - 0 - 0 - - - - The maximum amount of memory Minecraft is allowed to use. - - - M - - - 8 - - - 1048576 - - - 128 - - - 1024 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - PermGen Size - - - - - - - 0 - - - - - -XX:&PermSize= - - - permGenSpinBox - - - - - - - - 0 - 0 - - - - The amount of memory available to store loaded Java classes. - - - M - - - 4 - - - 999999999 - - - 8 - - - 64 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + + + + 0 + 0 + + + + The amount of memory Minecraft is started with. + + + MiB + + + 8 + + + 1048576 + + + 128 + + + 256 + + + + + + + Ma&ximum Memory Usage (-Xmx) + + + maxMemSpinBox + + + + + + + + 0 + 0 + + + + The maximum amount of memory Minecraft is allowed to use. + + + MiB + + + 8 + + + 1048576 + + + 128 + + + 1024 + + + + + + + &PermGen Size (-XX:PermSize) + + + permGenSpinBox + + + + + + + + 0 + 0 + + + + The amount of memory available to store loaded Java classes. + + + MiB + + + 4 + + + 999999999 + + + 8 + + + 64 + - Maximum Memory Notice + TextLabel @@ -609,11 +312,18 @@ + javaTestBtn + javaDownloadBtn javaPathTextBox + javaDetectBtn + javaBrowseBtn skipCompatibilityCheckBox skipWizardCheckBox autodetectJavaCheckBox autodownloadJavaCheckBox + minMemSpinBox + maxMemSpinBox + permGenSpinBox jvmArgsTextBox From a8ea072d36dbfcf0e67c9cedb605f57623d96a99 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 13:23:53 +0000 Subject: [PATCH 23/62] Make Services page nicer Signed-off-by: TheKodeToad --- launcher/ui/pages/global/APIPage.ui | 195 +++++++++++---------- launcher/ui/widgets/JavaSettingsWidget.cpp | 2 +- 2 files changed, 105 insertions(+), 92 deletions(-) diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index ab4bdf83e..3280558ab 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -20,40 +20,12 @@ 0 - -342 - 804 - 946 + -270 + 807 + 870 - - - - - 0 - 0 - - - - User Agent - - - - - - - - - Enter a custom User Agent here. The special string $LAUNCHER_VER will be replaced with the version of the launcher. - - - true - - - - - - @@ -86,7 +58,7 @@ - + Use Default true @@ -128,7 +100,7 @@ - + Use Default @@ -151,16 +123,48 @@ + + + + + 0 + 0 + + + + User Agent + + + + + + Use Default + + + + + + + Enter a custom User Agent here. The special string $LAUNCHER_VER will be replaced with the version of the launcher. + + + true + + + + + + - &Microsoft Authentication + &API Keys - &Client ID + &Microsoft Authentation Qt::RichText @@ -179,7 +183,7 @@ - (Default) + Use Default @@ -196,32 +200,23 @@ - - - - - - - true - - - &Modrinth - - - - - - true + + + + QSizePolicy::Fixed - - (None) + + + 0 + 6 + - + - + - &API Token + Mod&rinth Qt::RichText @@ -237,7 +232,17 @@ - + + + + true + + + Use None + + + + <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/api/#authentication">documentation</a> for more information.</p></body></html> @@ -250,32 +255,23 @@ - - - - - - - true - - - &CurseForge - - - - - - true + + + + QSizePolicy::Fixed - - (Default) + + + 0 + 6 + - + - + - API &Key + &CurseForge Qt::RichText @@ -291,7 +287,17 @@ - + + + + true + + + Use Default + + + + Note: you probably don't need to set this if CurseForge already works. @@ -301,26 +307,33 @@ - - - - - - - Technic - - + + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + - GUID Client ID + &Technic + + + technicClientID - (None) + Use Default diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index bd48f3faa..265385d03 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -298,7 +298,7 @@ void JavaSettingsWidget::updateThresholds() m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is close to your system memory capacity."))); m_ui->labelMaxMemNotice->show(); } else if (maxMem < minMem) { - m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is below the minimum memory allocation."))) + m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is below the minimum memory allocation."))); } else { m_ui->labelMaxMemNotice->hide(); } From 491b5e147370189ec8553ef5819ece448f9cd9e3 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 16:34:45 +0000 Subject: [PATCH 24/62] Correctly show max memory notice for max < min Signed-off-by: TheKodeToad --- launcher/ui/widgets/AppearanceWidget.ui | 24 ++++++++++++++++++++++ launcher/ui/widgets/JavaSettingsWidget.cpp | 1 + 2 files changed, 25 insertions(+) diff --git a/launcher/ui/widgets/AppearanceWidget.ui b/launcher/ui/widgets/AppearanceWidget.ui index d646cb9e0..deb5a94d4 100644 --- a/launcher/ui/widgets/AppearanceWidget.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -157,6 +157,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -208,6 +220,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 265385d03..f5435d16f 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -299,6 +299,7 @@ void JavaSettingsWidget::updateThresholds() m_ui->labelMaxMemNotice->show(); } else if (maxMem < minMem) { m_ui->labelMaxMemNotice->setText(warningColour.arg(tr("Your maximum memory allocation is below the minimum memory allocation."))); + m_ui->labelMaxMemNotice->show(); } else { m_ui->labelMaxMemNotice->hide(); } From 23a28fe762d09f4ea07b1b77def655cdf99072ee Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 17:19:09 +0000 Subject: [PATCH 25/62] Fix tooltip inconsistency Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index b358765a3..b70cc6c1b 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -29,7 +29,7 @@ 0 - 0 + -616 566 1296 @@ -325,7 +325,7 @@ - Disable using metadata provided by mod providers (like Modrinth or CurseForge) for mods. + Store version information provided by mod providers (like Modrinth or CurseForge) for mods. Keep track of mod metadata @@ -345,7 +345,7 @@ - Disable the automatic detection, installation, and updating of mod dependencies. + Automatically detect, install, and update mod dependencies. Install dependencies automatically @@ -355,7 +355,7 @@ - When creating a new modpack instance, do not suggest updating existing instances instead. + When creating a new modpack instance, suggest updating an existing instance instead. Suggest to update an existing instance From e2b85a2e2bf07751b5084a5686baf85e1fff12b8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 24 Mar 2025 17:24:18 +0000 Subject: [PATCH 26/62] Clang format Signed-off-by: TheKodeToad --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ecd606f43..bf9fa32ed 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -57,9 +57,9 @@ #include "ui/instanceview/AccessibleInstanceView.h" #include "ui/pages/BasePageProvider.h" -#include "ui/pages/global/AppearancePage.h" #include "ui/pages/global/APIPage.h" #include "ui/pages/global/AccountListPage.h" +#include "ui/pages/global/AppearancePage.h" #include "ui/pages/global/ExternalToolsPage.h" #include "ui/pages/global/JavaPage.h" #include "ui/pages/global/LanguagePage.h" From 910febeeb00295492cddff43c4fc212450d21e6a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 27 Mar 2025 00:37:39 +0000 Subject: [PATCH 27/62] Try to make getchoo requested changes Signed-off-by: TheKodeToad --- launcher/ui/pages/global/JavaPage.ui | 115 ++++------ launcher/ui/widgets/CustomCommands.cpp | 9 +- launcher/ui/widgets/CustomCommands.ui | 62 ++--- launcher/ui/widgets/EnvironmentVariables.cpp | 10 +- launcher/ui/widgets/EnvironmentVariables.ui | 41 ++-- launcher/ui/widgets/JavaSettingsWidget.ui | 108 ++++----- .../ui/widgets/MinecraftSettingsWidget.cpp | 9 +- .../ui/widgets/MinecraftSettingsWidget.ui | 212 ++++++++---------- 8 files changed, 266 insertions(+), 300 deletions(-) diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index bc5e9523f..3b5d797d6 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -17,18 +17,6 @@ - - 0 - - - 0 - - - 0 - - - 0 - @@ -49,8 +37,8 @@ 0 0 - 535 - 606 + 523 + 594 @@ -65,64 +53,55 @@ - Management + Installations - - - Downloaded Java Versions + + + + + Download + + + + + + + Remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Refresh + + + + + + + + + + 0 + 0 + - - - - - - - Download - - - - - - - Remove - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Refresh - - - - - - - - - - 0 - 0 - - - - - diff --git a/launcher/ui/widgets/CustomCommands.cpp b/launcher/ui/widgets/CustomCommands.cpp index 9b98d7409..45bd0cbea 100644 --- a/launcher/ui/widgets/CustomCommands.cpp +++ b/launcher/ui/widgets/CustomCommands.cpp @@ -44,13 +44,14 @@ CustomCommands::~CustomCommands() CustomCommands::CustomCommands(QWidget* parent) : QWidget(parent), ui(new Ui::CustomCommands) { ui->setupUi(this); + connect(ui->overrideCheckBox, &QCheckBox::toggled, ui->customCommandsWidget, &QWidget::setEnabled); } void CustomCommands::initialize(bool checkable, bool checked, const QString& prelaunch, const QString& wrapper, const QString& postexit) { - ui->customCommandsGroupBox->setCheckable(checkable); + ui->overrideCheckBox->setVisible(checkable); if (checkable) { - ui->customCommandsGroupBox->setChecked(checked); + ui->overrideCheckBox->setChecked(checked); } ui->preLaunchCmdTextBox->setText(prelaunch); ui->wrapperCmdTextBox->setText(wrapper); @@ -64,9 +65,9 @@ void CustomCommands::retranslate() bool CustomCommands::checked() const { - if (!ui->customCommandsGroupBox->isCheckable()) + if (!ui->overrideCheckBox->isVisible()) return true; - return ui->customCommandsGroupBox->isChecked(); + return ui->overrideCheckBox->isChecked(); } QString CustomCommands::prelaunchCommand() const diff --git a/launcher/ui/widgets/CustomCommands.ui b/launcher/ui/widgets/CustomCommands.ui index b485c293e..53fca9419 100644 --- a/launcher/ui/widgets/CustomCommands.ui +++ b/launcher/ui/widgets/CustomCommands.ui @@ -24,20 +24,30 @@ 0 - + + + Override &Global Settings + + + true + + + + + true - - &Custom Commands - - - true - - - false - + + 0 + + + 0 + + + 0 + @@ -48,9 +58,25 @@ + + + + + + + P&ost-exit command: + + + labelPostExitCmd + + + + + + @@ -61,22 +87,6 @@ - - - - - - - P&ost-exit command: - - - postExitCmdTextBox - - - - - - diff --git a/launcher/ui/widgets/EnvironmentVariables.cpp b/launcher/ui/widgets/EnvironmentVariables.cpp index 633fc6122..653f0d23d 100644 --- a/launcher/ui/widgets/EnvironmentVariables.cpp +++ b/launcher/ui/widgets/EnvironmentVariables.cpp @@ -50,6 +50,8 @@ EnvironmentVariables::EnvironmentVariables(QWidget* parent) : QWidget(parent), u }); connect(ui->clear, &QPushButton::clicked, this, [this] { ui->list->clear(); }); + + connect(ui->overrideCheckBox, &QCheckBox::toggled, ui->settingsWidget, &QWidget::setEnabled); } EnvironmentVariables::~EnvironmentVariables() @@ -60,8 +62,8 @@ EnvironmentVariables::~EnvironmentVariables() void EnvironmentVariables::initialize(bool instance, bool override, const QMap& value) { // update widgets to settings - ui->groupBox->setCheckable(instance); - ui->groupBox->setChecked(override); + ui->overrideCheckBox->setVisible(instance); + ui->overrideCheckBox->setChecked(override); // populate ui->list->clear(); @@ -94,9 +96,9 @@ void EnvironmentVariables::retranslate() bool EnvironmentVariables::override() const { - if (!ui->groupBox->isCheckable()) + if (!ui->overrideCheckBox->isVisible()) return false; - return ui->groupBox->isChecked(); + return ui->overrideCheckBox->isChecked(); } QMap EnvironmentVariables::value() const diff --git a/launcher/ui/widgets/EnvironmentVariables.ui b/launcher/ui/widgets/EnvironmentVariables.ui index 828626d12..cc52b5d10 100644 --- a/launcher/ui/widgets/EnvironmentVariables.ui +++ b/launcher/ui/widgets/EnvironmentVariables.ui @@ -14,27 +14,34 @@ Form - - 0 - - - 0 - - - 0 - - - 0 - - - - &Environment Variables + + + Override &Global Settings - + true - + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 5cc894b8e..3094aadc8 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -26,37 +26,6 @@ 0 - - - - - - Test S&ettings - - - - - - - Open Java &Downloader - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - @@ -72,6 +41,16 @@ false + + + + Java &Executable + + + javaPathTextBox + + + @@ -99,23 +78,6 @@ - - - - If enabled, the launcher will not check if an instance is compatible with the selected Java version. - - - Skip Java compatibility checks - - - - - - - Auto-&detect Java version - - - @@ -136,16 +98,54 @@ - - + + - Java &Executable - - - javaPathTextBox + Auto-&detect Java version + + + + If enabled, the launcher will not check if an instance is compatible with the selected Java version. + + + Skip Java compatibility checks + + + + + + + + + Test S&ettings + + + + + + + Open Java &Downloader + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.cpp b/launcher/ui/widgets/MinecraftSettingsWidget.cpp index cec7f267f..2f22ae54a 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.cpp +++ b/launcher/ui/widgets/MinecraftSettingsWidget.cpp @@ -50,14 +50,11 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance, m_ui->setupUi(this); if (m_instance == nullptr) { - for (int i = m_ui->settingsTabs->count() - 1; i >= 0; --i) { - const QString name = m_ui->settingsTabs->widget(i)->objectName(); - - if (name == "javaPage" || name == "launchPage") - m_ui->settingsTabs->removeTab(i); - } + m_ui->settingsTabs->removeTab(1); m_ui->openGlobalSettingsButton->setVisible(false); + m_ui->instanceAccountGroupBox->hide(); + m_ui->serverJoinGroupBox->hide(); } else { m_javaSettings = new JavaSettingsWidget(m_instance, this); m_ui->javaScrollArea->setWidget(m_javaSettings); diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index 34fa9af80..0edbeacb7 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -58,9 +58,9 @@ 0 - 0 - 610 - 610 + -125 + 603 + 786 @@ -203,6 +203,79 @@ + + + + &Override Default Account + + + true + + + false + + + + + + + 0 + 0 + + + + Account + + + + + + + + 0 + 0 + + + + + + + + + + + Enable &Auto-join + + + true + + + false + + + + + + Server address + + + + + + + + + + Singleplayer world + + + + + + + + + @@ -352,7 +425,7 @@ 0 0 624 - 291 + 287 @@ -375,8 +448,8 @@ 0 0 - 610 - 501 + 603 + 470 @@ -564,118 +637,6 @@ - - - Launch - - - - - - true - - - - - 0 - 0 - 624 - 291 - - - - - - - Override default &account - - - true - - - false - - - - - - - 0 - 0 - - - - Account - - - - - - - - 0 - 0 - - - - - - - - - - - Set a &target to join on launch - - - true - - - false - - - - - - Server address - - - - - - - - - - Singleplayer world - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Custom Commands @@ -691,6 +652,18 @@ Environment Variables + + 0 + + + 0 + + + 0 + + + 0 + @@ -737,9 +710,6 @@ enableMangoHud useDiscreteGpuCheck useZink - scrollArea_3 - instanceAccountGroupBox - serverJoinGroupBox serverJoinAddressButton serverJoinAddress worldJoinButton From 1ce343fb97d2ce88dc4033c976c1994d71278576 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 27 Mar 2025 00:48:56 +0000 Subject: [PATCH 28/62] Try to make Minecraft general page easier to understand - remove misc Signed-off-by: TheKodeToad --- .../ui/widgets/MinecraftSettingsWidget.cpp | 34 ++--- .../ui/widgets/MinecraftSettingsWidget.ui | 143 ++++++++---------- 2 files changed, 75 insertions(+), 102 deletions(-) diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.cpp b/launcher/ui/widgets/MinecraftSettingsWidget.cpp index 2f22ae54a..07761207a 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.cpp +++ b/launcher/ui/widgets/MinecraftSettingsWidget.cpp @@ -68,7 +68,6 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance, tr("Warning: The maximized option is " "not fully supported on this Minecraft version.")); - m_ui->miscellaneousSettingsBox->setCheckable(true); m_ui->consoleSettingsBox->setCheckable(true); m_ui->windowSizeGroupBox->setCheckable(true); m_ui->nativeWorkaroundsGroupBox->setCheckable(true); @@ -136,11 +135,14 @@ void MinecraftSettingsWidget::loadSettings() settings = APPLICATION->settings(); // Game Window - m_ui->windowSizeGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideWindow").toBool()); + m_ui->windowSizeGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideWindow").toBool() || + settings->get("OverrideMiscellaneous").toBool()); m_ui->windowSizeGroupBox->setChecked(settings->get("OverrideWindow").toBool()); m_ui->maximizedCheckBox->setChecked(settings->get("LaunchMaximized").toBool()); m_ui->windowWidthSpinBox->setValue(settings->get("MinecraftWinWidth").toInt()); m_ui->windowHeightSpinBox->setValue(settings->get("MinecraftWinHeight").toInt()); + m_ui->closeAfterLaunchCheck->setChecked(settings->get("CloseAfterLaunch").toBool()); + m_ui->quitAfterGameStopCheck->setChecked(settings->get("QuitAfterGameStop").toBool()); // Game Time m_ui->gameTimeGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideGameTime").toBool()); @@ -155,11 +157,6 @@ void MinecraftSettingsWidget::loadSettings() m_ui->autoCloseConsoleCheck->setChecked(settings->get("AutoCloseConsole").toBool()); m_ui->showConsoleErrorCheck->setChecked(settings->get("ShowConsoleOnError").toBool()); - // Miscellaneous - m_ui->miscellaneousSettingsBox->setChecked(settings->get("OverrideMiscellaneous").toBool()); - m_ui->closeAfterLaunchCheck->setChecked(settings->get("CloseAfterLaunch").toBool()); - m_ui->quitAfterGameStopCheck->setChecked(settings->get("QuitAfterGameStop").toBool()); - if (m_javaSettings != nullptr) m_javaSettings->loadSettings(); @@ -242,19 +239,6 @@ void MinecraftSettingsWidget::saveSettings() { SettingsObject::Lock lock(settings); - // Miscellaneous - bool miscellaneous = m_instance == nullptr || m_ui->miscellaneousSettingsBox->isChecked(); - - if (m_instance != nullptr) - settings->set("OverrideMiscellaneous", miscellaneous); - - if (miscellaneous) { - settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked()); - settings->set("QuitAfterGameStop", m_ui->quitAfterGameStopCheck->isChecked()); - } else { - settings->reset("CloseAfterLaunch"); - settings->reset("QuitAfterGameStop"); - } // Console bool console = m_instance == nullptr || m_ui->consoleSettingsBox->isChecked(); @@ -272,20 +256,26 @@ void MinecraftSettingsWidget::saveSettings() settings->reset("ShowConsoleOnError"); } - // Window Size + // Game Window bool window = m_instance == nullptr || m_ui->windowSizeGroupBox->isChecked(); - if (m_instance != nullptr) + if (m_instance != nullptr) { settings->set("OverrideWindow", window); + settings->set("OverrideMiscellaneous", window); + } if (window) { settings->set("LaunchMaximized", m_ui->maximizedCheckBox->isChecked()); settings->set("MinecraftWinWidth", m_ui->windowWidthSpinBox->value()); settings->set("MinecraftWinHeight", m_ui->windowHeightSpinBox->value()); + settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked()); + settings->set("QuitAfterGameStop", m_ui->quitAfterGameStopCheck->isChecked()); } else { settings->reset("LaunchMaximized"); settings->reset("MinecraftWinWidth"); settings->reset("MinecraftWinHeight"); + settings->reset("CloseAfterLaunch"); + settings->reset("QuitAfterGameStop"); } // Custom Commands diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index 0edbeacb7..b71250c47 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -58,9 +58,9 @@ 0 - -125 + 0 603 - 786 + 744 @@ -200,6 +200,59 @@ + + + + Close the launcher after the game window opens + + + + + + + Quit the launcher after the game window closes + + + + + + + + + + true + + + &Console Window + + + false + + + false + + + + + + Show console window while the game is running + + + + + + + Automatically close console window when the game quits + + + + + + + Show console window when the game crashes + + + @@ -253,6 +306,13 @@ false + + + + Singleplayer world + + + @@ -263,14 +323,7 @@ - - - - Singleplayer world - - - - + @@ -322,74 +375,6 @@ - - - - true - - - &Console - - - false - - - false - - - - - - Show console while the game is running - - - - - - - Automatically close console when the game quits - - - - - - - Show console when the game crashes - - - - - - - - - - &Miscellaneous - - - false - - - false - - - - - - Close the launcher after game window opens - - - - - - - Quit the launcher after game window closes - - - - - - @@ -698,8 +683,6 @@ showConsoleCheck autoCloseConsoleCheck showConsoleErrorCheck - closeAfterLaunchCheck - quitAfterGameStopCheck javaScrollArea scrollArea_2 onlineFixes From 7e5178cf8117be59f350e5c89b6e210d9a5e6d5e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 27 Mar 2025 01:08:26 +0000 Subject: [PATCH 29/62] Visual cleanup Signed-off-by: TheKodeToad --- launcher/ui/pages/global/APIPage.ui | 28 ++- launcher/ui/widgets/CustomCommands.ui | 47 ++++- launcher/ui/widgets/JavaSettingsWidget.ui | 50 ++++- .../ui/widgets/MinecraftSettingsWidget.cpp | 1 - .../ui/widgets/MinecraftSettingsWidget.ui | 195 ++++++++++-------- 5 files changed, 210 insertions(+), 111 deletions(-) diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 3280558ab..0b9dde764 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -20,9 +20,9 @@ 0 - -270 - 807 - 870 + 0 + 804 + 832 @@ -84,19 +84,6 @@ Meta&data Server - - - - Base URL - - - Qt::RichText - - - true - - - @@ -202,6 +189,9 @@ + + Qt::Vertical + QSizePolicy::Fixed @@ -257,6 +247,9 @@ + + Qt::Vertical + QSizePolicy::Fixed @@ -309,6 +302,9 @@ + + Qt::Vertical + QSizePolicy::Fixed diff --git a/launcher/ui/widgets/CustomCommands.ui b/launcher/ui/widgets/CustomCommands.ui index 53fca9419..cabd1372d 100644 --- a/launcher/ui/widgets/CustomCommands.ui +++ b/launcher/ui/widgets/CustomCommands.ui @@ -51,42 +51,71 @@ - &Pre-launch command: + &Pre-launch Command preLaunchCmdTextBox - - + + + + Qt::Vertical + + + + 0 + 6 + + + - + - + + + + - P&ost-exit command: + P&ost-exit Command labelPostExitCmd - + - + - &Wrapper command: + &Wrapper Command wrapperCmdTextBox + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 3094aadc8..366b8d6fc 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -202,6 +202,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + @@ -240,6 +256,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + @@ -278,10 +310,26 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + - TextLabel + Memory Notice diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.cpp b/launcher/ui/widgets/MinecraftSettingsWidget.cpp index 07761207a..c3d342d42 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.cpp +++ b/launcher/ui/widgets/MinecraftSettingsWidget.cpp @@ -137,7 +137,6 @@ void MinecraftSettingsWidget::loadSettings() // Game Window m_ui->windowSizeGroupBox->setChecked(m_instance == nullptr || settings->get("OverrideWindow").toBool() || settings->get("OverrideMiscellaneous").toBool()); - m_ui->windowSizeGroupBox->setChecked(settings->get("OverrideWindow").toBool()); m_ui->maximizedCheckBox->setChecked(settings->get("LaunchMaximized").toBool()); m_ui->windowWidthSpinBox->setValue(settings->get("MinecraftWinWidth").toInt()); m_ui->windowHeightSpinBox->setValue(settings->get("MinecraftWinHeight").toInt()); diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index b71250c47..4c317c15d 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -58,9 +58,9 @@ 0 - 0 + -130 603 - 744 + 812 @@ -200,17 +200,33 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + - Close the launcher after the game window opens + When the game window opens, hide the launcher - Quit the launcher after the game window closes + When the game window closes, quit the launcher @@ -235,97 +251,24 @@ - Show console window while the game is running - - - - - - - Automatically close console window when the game quits + When the game is launched, show the console window - Show console window when the game crashes - - - - - - - - - - &Override Default Account - - - true - - - false - - - - - - - 0 - 0 - - - - Account + When the game crashes, show the console window - - - - 0 - 0 - - - - - - - - - - - Enable &Auto-join - - - true - - - false - - - - + - Singleplayer world + When the game quits, hide the console window - - - - Server address - - - - - - - - - @@ -375,6 +318,93 @@ + + + + Override &Default Account + + + true + + + false + + + + + + + 0 + 0 + + + + Account + + + + + + + + 0 + 0 + + + + + + + + + + + Enable Auto-&join + + + true + + + false + + + + + + Server address + + + + + + + + 200 + 16777215 + + + + + + + + Singleplayer world + + + + + + + + 0 + 0 + + + + + + + @@ -682,7 +712,6 @@ showGameTimeWithoutDays showConsoleCheck autoCloseConsoleCheck - showConsoleErrorCheck javaScrollArea scrollArea_2 onlineFixes @@ -694,9 +723,7 @@ useDiscreteGpuCheck useZink serverJoinAddressButton - serverJoinAddress worldJoinButton - worldsCb From 3b393e8d615256bc02e390198e41b7ac6a249a81 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 27 Mar 2025 01:20:38 +0000 Subject: [PATCH 30/62] Fix Java padding Signed-off-by: TheKodeToad --- launcher/ui/pages/global/JavaPage.ui | 12 ++++++++++++ launcher/ui/widgets/JavaSettingsWidget.ui | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 3b5d797d6..6b350fe07 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -42,6 +42,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 366b8d6fc..c34b07cfa 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -14,18 +14,6 @@ Form - - 0 - - - 0 - - - 0 - - - 0 - From 36a89b0839dda900565b65ef2ab00214c7d43ca5 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 29 Mar 2025 20:24:21 +0000 Subject: [PATCH 31/62] Fix CustomCommands spacing Signed-off-by: TheKodeToad --- launcher/ui/widgets/CustomCommands.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/ui/widgets/CustomCommands.ui b/launcher/ui/widgets/CustomCommands.ui index cabd1372d..c1b4558a8 100644 --- a/launcher/ui/widgets/CustomCommands.ui +++ b/launcher/ui/widgets/CustomCommands.ui @@ -63,6 +63,9 @@ Qt::Vertical + + QSizePolicy::Fixed + 0 From ec2552e501713119a2c6b8820ec40c35f93cc326 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 10:40:55 +0100 Subject: [PATCH 32/62] Make padding consistent Signed-off-by: TheKodeToad --- launcher/ui/pages/global/APIPage.ui | 28 +++++++++++++------ launcher/ui/pages/global/AppearancePage.h | 11 ++++---- launcher/ui/pages/global/ExternalToolsPage.ui | 16 +++++++++-- launcher/ui/pages/global/JavaPage.ui | 16 +++++++++-- launcher/ui/pages/global/LauncherPage.ui | 18 ++++++++++-- launcher/ui/pages/global/ProxyPage.ui | 11 +++++++- 6 files changed, 78 insertions(+), 22 deletions(-) diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 0b9dde764..9352162f0 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -11,6 +11,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -21,7 +33,7 @@ 0 0 - 804 + 816 832 @@ -84,13 +96,6 @@ Meta&data Server - - - - Use Default - - - @@ -107,6 +112,13 @@ + + + + Use Default + + + diff --git a/launcher/ui/pages/global/AppearancePage.h b/launcher/ui/pages/global/AppearancePage.h index bf58ebb53..29b2d34bf 100644 --- a/launcher/ui/pages/global/AppearancePage.h +++ b/launcher/ui/pages/global/AppearancePage.h @@ -36,13 +36,12 @@ #pragma once #include -#include - -#include -#include -#include +#include +#include "Application.h" #include "java/JavaChecker.h" +#include "translations/TranslationsModel.h" #include "ui/pages/BasePage.h" +#include "ui/widgets/AppearanceWidget.h" class QTextCharFormat; class SettingsObject; @@ -51,7 +50,7 @@ class AppearancePage : public AppearanceWidget, public BasePage { Q_OBJECT public: - explicit AppearancePage(QWidget *parent = nullptr) : AppearanceWidget(false, parent) {} + explicit AppearancePage(QWidget* parent = nullptr) : AppearanceWidget(false, parent) { layout()->setContentsMargins(0, 0, 6, 0); } QString displayName() const override { return tr("Appearance"); } QIcon icon() const override { return APPLICATION->getThemedIcon("appearance"); } diff --git a/launcher/ui/pages/global/ExternalToolsPage.ui b/launcher/ui/pages/global/ExternalToolsPage.ui index 37eb7de3e..6667f34d9 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.ui +++ b/launcher/ui/pages/global/ExternalToolsPage.ui @@ -11,6 +11,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -21,8 +33,8 @@ 0 0 - 653 - 803 + 669 + 819 diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 6b350fe07..a40e38868 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -17,6 +17,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -37,8 +49,8 @@ 0 0 - 523 - 594 + 535 + 606 diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index b70cc6c1b..3821c09c4 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -17,6 +17,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -29,9 +41,9 @@ 0 - -616 - 566 - 1296 + 0 + 575 + 1294 diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 830ae1ac8..c8882a9dd 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -17,13 +17,22 @@ + + 0 + + + 0 + + + 0 + This only applies to the launcher. Minecraft does not accept proxy settings. - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true From a0c0262a197495e1ae509209da2636685a0a7a39 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 11:39:26 +0100 Subject: [PATCH 33/62] Delete libraries/filesystem Signed-off-by: TheKodeToad --- libraries/filesystem | 1 - 1 file changed, 1 deletion(-) delete mode 160000 libraries/filesystem diff --git a/libraries/filesystem b/libraries/filesystem deleted file mode 160000 index 076592ce6..000000000 --- a/libraries/filesystem +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 076592ce6e64568521b88a11881aa36b3d3f7048 From e04acdb8fbb120fb13bf5d5dcfaf9a69a219ffae Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 11:44:19 +0100 Subject: [PATCH 34/62] Cleanup modpack update prompt phrasing Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 2d04093d2..769721dd5 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -41,7 +41,7 @@ 0 - 0 + -312 575 1368 @@ -415,7 +415,7 @@ When creating a new modpack instance, suggest updating an existing instance instead. - Suggest to update an existing instance + Suggest to update an existing instance during modpack installation From 1a76e0492567e3d8b3e171de3ca1ac7f4b62849a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 11:58:41 +0100 Subject: [PATCH 35/62] Stop OK or Browse from getting implicit focus; add accelerator Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index bfa9ebdb0..3200a7c39 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -21,9 +21,7 @@ #include #include "Application.h" -#include "settings/SettingsObject.h" -#include "ui/widgets/IconLabel.h" #include "ui/widgets/PageContainer.h" PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidget* parent) : QDialog(parent) @@ -31,14 +29,22 @@ PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidge setWindowTitle(pageProvider->dialogTitle()); m_container = new PageContainer(pageProvider, std::move(defaultId), this); - QVBoxLayout* mainLayout = new QVBoxLayout(this); + auto* mainLayout = new QVBoxLayout(this); + + auto* focusStealer = new QPushButton(this); + mainLayout->addWidget(focusStealer); + focusStealer->setDefault(true); + focusStealer->hide(); + mainLayout->addWidget(m_container); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - buttons->button(QDialogButtonBox::Ok)->setDefault(true); + auto* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttons->button(QDialogButtonBox::Ok)->setText(tr("&OK")); + buttons->button(QDialogButtonBox::Cancel)->setText(tr("&Cancel")); buttons->button(QDialogButtonBox::Help)->setText(tr("Help")); buttons->setContentsMargins(6, 0, 6, 0); m_container->addButtons(buttons); From 2c869c7a02391ebb6f48702f367f41b4acefc6ff Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 12:09:13 +0100 Subject: [PATCH 36/62] Revert to old close behaviour Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 19 +++++++------------ launcher/ui/pagedialog/PageDialog.h | 10 ++++------ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 3200a7c39..d01c2217b 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -14,6 +14,7 @@ */ #include "PageDialog.h" +#include #include #include @@ -53,22 +54,16 @@ PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidge connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &PageDialog::reject); connect(buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help); - connect(this, &QDialog::accepted, this, &PageDialog::onAccepted); - connect(this, &QDialog::rejected, this, &PageDialog::storeGeometry); - restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } -void PageDialog::onAccepted() + +void PageDialog::closeEvent([[maybe_unused]] QCloseEvent* event) { - qDebug() << "Paged dialog accepted"; + qDebug() << "Paged dialog close requested"; if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; - emit applied(); + APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); + qDebug() << "Paged dialog geometry saved"; + QDialog::closeEvent(event); } } - -void PageDialog::storeGeometry() -{ - APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); - qDebug() << "Paged dialog geometry saved"; -} diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index d4af862f3..cc250af75 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -25,13 +25,11 @@ class PageDialog : public QDialog { explicit PageDialog(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0); virtual ~PageDialog() {} - signals: - void applied(); + signals: + void applied(); - - private slots: - void onAccepted(); - void storeGeometry(); + private: + void closeEvent(QCloseEvent* event) override; private: PageContainer* m_container; From 4a2e4e9dc21dcb3458ccb8c7cdeacecd147147a2 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 12:32:14 +0100 Subject: [PATCH 37/62] Use title case for 'When Renaming Instances...' Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 769721dd5..4421215a7 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -41,7 +41,7 @@ 0 - -312 + 0 575 1368 @@ -102,7 +102,7 @@ - When renaming instances... + When Renaming Instances... From 33ac9e3f475056d005406baa65bed9a0b1696b3d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 12:39:25 +0100 Subject: [PATCH 38/62] Apparently this is correct Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 4421215a7..b5374e7cc 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -126,7 +126,7 @@ - Never rename the folder - only the displayed name + Never rename the folder—only the displayed name From 917abd60e1e1872acc4feee280537c1c0a161a04 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 13:08:58 +0100 Subject: [PATCH 39/62] Remove accidental qevent import Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index d01c2217b..aad204979 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -14,7 +14,6 @@ */ #include "PageDialog.h" -#include #include #include From 54e63fee6e19e59ffe702ce074587eb9c5c9822a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 13:17:16 +0100 Subject: [PATCH 40/62] Fix spacer Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index b5374e7cc..03b93e425 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -136,9 +136,12 @@ Qt::Vertical + + QSizePolicy::Fixed + - 20 + 0 6 From 53305bf5a7a0fa3bb4cfb508c96d3f70d2feb9b4 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 14:17:03 +0100 Subject: [PATCH 41/62] Align task spinboxes Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 26 +++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 03b93e425..8f5eb69d5 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -41,7 +41,7 @@ 0 - 0 + -672 575 1368 @@ -513,6 +513,12 @@ 0 + + + 60 + 0 + + 1 @@ -549,6 +555,12 @@ 0 + + + 60 + 0 + + 1 @@ -585,6 +597,12 @@ 0 + + + 60 + 0 + + 0 @@ -624,6 +642,12 @@ 0 + + + 60 + 0 + + s From be5a1b47acc19aa7e186bca318028233b6504665 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 14:20:59 +0100 Subject: [PATCH 42/62] Make PermGen max consistent Signed-off-by: TheKodeToad --- launcher/ui/widgets/JavaSettingsWidget.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index c34b07cfa..8a8b20935 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -288,7 +288,7 @@ 4 - 999999999 + 1048576 8 From c7401ad649187b5431014d7f54647664b16fd25e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 14:27:47 +0100 Subject: [PATCH 43/62] Try to avoid cramming too much next to file path boxes Signed-off-by: TheKodeToad --- launcher/ui/pages/global/ExternalToolsPage.ui | 60 ++++--- launcher/ui/widgets/JavaSettingsWidget.ui | 152 +++++++++++------- 2 files changed, 133 insertions(+), 79 deletions(-) diff --git a/launcher/ui/pages/global/ExternalToolsPage.ui b/launcher/ui/pages/global/ExternalToolsPage.ui index 6667f34d9..b094e3693 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.ui +++ b/launcher/ui/pages/global/ExternalToolsPage.ui @@ -106,13 +106,6 @@ - - - - Check - - - @@ -122,6 +115,19 @@ + + + + + 0 + 0 + + + + Check + + + @@ -179,13 +185,6 @@ - - - - Check - - - @@ -195,6 +194,19 @@ + + + + + 0 + 0 + + + + Check + + + @@ -233,13 +245,6 @@ - - - - Check - - - @@ -249,6 +254,19 @@ + + + + + 0 + 0 + + + + Check + + + diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 8a8b20935..4028ca544 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -29,21 +29,15 @@ false - - + + - Java &Executable - - - javaPathTextBox + Auto-&detect Java version - - - - - + + @@ -53,57 +47,27 @@ - - - 0 - 0 - - &Browse + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - Automatically downloads and selects the Java build recommended by Mojang. - - - Auto-download &Mojang Java - - - - - - - If enabled, the launcher won't prompt you to choose a Java version if one is not found on startup. - - - Skip Java setup prompt on startup - - - - - - - Auto-&detect Java version - - - - - - - If enabled, the launcher will not check if an instance is compatible with the selected Java version. - - - Skip Java compatibility checks - - - - + @@ -134,6 +98,81 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + + + Automatically downloads and selects the Java build recommended by Mojang. + + + Auto-download &Mojang Java + + + + + + + If enabled, the launcher will not check if an instance is compatible with the selected Java version. + + + Skip Java compatibility checks + + + + + + + + + + Java &Executable + + + javaPathTextBox + + + + + + + If enabled, the launcher won't prompt you to choose a Java version if one is not found on startup. + + + Skip Java setup prompt on startup + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + @@ -350,9 +389,6 @@ javaTestBtn javaDownloadBtn - javaPathTextBox - javaDetectBtn - javaBrowseBtn skipCompatibilityCheckBox skipWizardCheckBox autodetectJavaCheckBox From 76db89460b3faf53e8557cd9e16ad98dcfaad386 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 19:21:38 +0100 Subject: [PATCH 44/62] Redo layouts Signed-off-by: TheKodeToad --- launcher/ui/pages/global/APIPage.ui | 11 +- launcher/ui/pages/global/LauncherPage.ui | 508 ++++++++---------- launcher/ui/pages/global/ProxyPage.ui | 67 ++- launcher/ui/widgets/AppearanceWidget.ui | 173 +++--- launcher/ui/widgets/JavaSettingsWidget.ui | 245 ++++----- .../ui/widgets/MinecraftSettingsWidget.ui | 362 ++++++------- .../ui/widgets/ThemeCustomizationWidget.ui | 171 ------ 7 files changed, 665 insertions(+), 872 deletions(-) delete mode 100644 launcher/ui/widgets/ThemeCustomizationWidget.ui diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 9352162f0..c6a4593fc 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -32,7 +32,7 @@ 0 - 0 + -216 816 832 @@ -55,7 +55,14 @@ - + + + + 0 + 0 + + + diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 8f5eb69d5..22ac6a018 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -6,8 +6,8 @@ 0 0 - 600 - 700 + 767 + 796 @@ -41,9 +41,9 @@ 0 - -672 - 575 - 1368 + -356 + 742 + 1148 @@ -55,7 +55,7 @@ User Interface - + @@ -102,7 +102,7 @@ - When Renaming Instances... + Instance Renaming @@ -165,65 +165,60 @@ Updater - - + + + + + + + How Often? + + + + + + + + 0 + 0 + + + + Set to 0 to only check on launch + + + On Launch + + + hours + + + Every + + + 0 + + + 168 + + + + + + + Qt::Horizontal + + + + + + Check for updates automatically - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - - - How Often? - - - - - - - - 0 - 0 - - - - Set to 0 to only check on launch - - - On Launch - - - hours - - - Every - - - 0 - - - 168 - - - @@ -232,24 +227,14 @@ Folders - - - - - &Icons - - - iconsDirTextBox - - + + + - - + + - &Downloads - - - downloadsDirTextBox + Browse @@ -263,39 +248,6 @@ - - - - &Skins - - - skinsDirTextBox - - - - - - - I&nstances - - - instDirTextBox - - - - - - - - - - Browse - - - - - - @@ -303,40 +255,13 @@ - - - - - - - - - - - + + - Browse + &Skins - - - - - - Browse - - - - - - - Browse - - - - - - - Browse + + skinsDirTextBox @@ -350,9 +275,79 @@ + + + + Browse + + + + + + + &Downloads + + + downloadsDirTextBox + + + + + + + + + + I&nstances + + + instDirTextBox + + + + + + + Browse + + + + + + + Browse + + + + + + + + + + Browse + + + + + + + + + + + + + &Icons + + + iconsDirTextBox + + + @@ -430,9 +425,18 @@ Console - - + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + 0 + 0 + + Log History &Limit @@ -441,7 +445,7 @@ - + @@ -466,23 +470,7 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - + &Stop logging when log overflows @@ -497,99 +485,8 @@ Tasks - - - - - Number of concurrent tasks - - - - - - - - 0 - 0 - - - - - 60 - 0 - - - - 1 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - - - Number of concurrent downloads - - - - - - - - 0 - 0 - - - - - 60 - 0 - - - - 1 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - - - Number of manual retries - - - - + + @@ -608,33 +505,26 @@ - - - - Qt::Vertical + + + + + 0 + 0 + - - QSizePolicy::Fixed - - + - 0 - 6 + 60 + 0 - - - - - - Seconds to wait until the requests are terminated - - - Timeout for HTTP requests + + 1 - + @@ -653,6 +543,63 @@ + + + + Retry Limit + + + + + + + Concurrent Download Limit + + + + + + + Seconds to wait until the requests are terminated + + + HTTP Timeout + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + 1 + + + + + + + Concurrent Task Limit + + + + + + + Qt::Horizontal + + + @@ -678,21 +625,8 @@ scrollArea autoUpdateCheckBox - instDirTextBox - instDirBrowseBtn - modsDirTextBox - modsDirBrowseBtn - iconsDirTextBox - iconsDirBrowseBtn - javaDirTextBox - javaDirBrowseBtn - skinsDirTextBox - skinsDirBrowseBtn - downloadsDirTextBox - downloadsDirBrowseBtn metadataEnableBtn dependenciesEnableBtn - sortByNameBtn diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index c8882a9dd..3042a4bba 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -51,7 +51,7 @@ Uses your system's default proxy settings. - S&ystem Settings + Use S&ystem Settings proxyGroup @@ -99,6 +99,18 @@ + + + 0 + 0 + + + + + 300 + 0 + + 127.0.0.1 @@ -120,6 +132,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -128,30 +153,30 @@ Authentication - - - - - - - - Note: Proxy username and password are stored in plain text inside the launcher's configuration file! - - - true - - - + - &Username: + &Username proxyUserEdit + + + + + + + &Password + + + proxyPassEdit + + + @@ -159,13 +184,13 @@ - - + + - &Password: + Note: Proxy username and password are stored in plain text inside the launcher's configuration file! - - proxyPassEdit + + true diff --git a/launcher/ui/widgets/AppearanceWidget.ui b/launcher/ui/widgets/AppearanceWidget.ui index deb5a94d4..d56e6f031 100644 --- a/launcher/ui/widgets/AppearanceWidget.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -142,9 +142,65 @@ - + + + + + Console Font + + + + + + + + + + + 0 + 0 + + + + 5 + + + 16 + + + 11 + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + + + - Console Font + Cat Opacity @@ -169,48 +225,9 @@ 0 - - - - - - - 5 - - - 16 - - - 11 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - - - Cat Opacity - - - @@ -232,20 +249,34 @@ 0 - + + + + false + + + Opaque + + + + Qt::Horizontal - - - 40 - 20 - - - + + + + false + + + Transparent + + + + @@ -261,29 +292,25 @@ - - - - false - - - Transparent - - - - - - - false - - - Opaque - - - + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 6 + + + + @@ -499,12 +526,6 @@ Qt::Horizontal - - - 0 - 0 - - @@ -545,8 +566,6 @@ catPackComboBox catPackFolder reloadThemesButton - consoleFont - fontSizeBox catOpacitySlider diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 4028ca544..027b20d2f 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -7,13 +7,13 @@ 0 0 500 - 1123 + 1000 Form - + @@ -190,126 +190,22 @@ false - - - + + + - M&inimum Memory Usage (-Xms) - - - minMemSpinBox + Memory Notice - - - - - 0 - 0 - - - - The amount of memory Minecraft is started with. - - - MiB - - - 8 - - - 1048576 - - - 128 - - - 256 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - + + - Ma&ximum Memory Usage (-Xmx) - - - maxMemSpinBox + (-XX:PermSize) - - - - - 0 - 0 - - - - The maximum amount of memory Minecraft is allowed to use. - - - MiB - - - 8 - - - 1048576 - - - 128 - - - 1024 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - - - &PermGen Size (-XX:PermSize) - - - permGenSpinBox - - - - + @@ -337,29 +233,119 @@ - - - - Qt::Vertical + + + + + 0 + 0 + - - QSizePolicy::Fixed + + The maximum amount of memory Minecraft is allowed to use. + + + MiB + + + 8 + + + 1048576 + + + 128 + + + 1024 + + + + + + + (-Xmx) + + + + + + + + 0 + 0 + + + + The amount of memory Minecraft is started with. + + + MiB + + + 8 + + + 1048576 + + + 128 + + + 256 + + + + + + + &PermGen Size + + + permGenSpinBox + + + + + + + (-Xms) + + + + + + + Ma&ximum Memory + + + maxMemSpinBox + + + + + + + M&inimum Memory + + + minMemSpinBox + + + + + + + Qt::Horizontal 0 - 6 + 0 - - - - Memory Notice - - - @@ -393,9 +379,6 @@ skipWizardCheckBox autodetectJavaCheckBox autodownloadJavaCheckBox - minMemSpinBox - maxMemSpinBox - permGenSpinBox jvmArgsTextBox diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index 4c317c15d..9a9adb8b7 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -7,7 +7,7 @@ 0 0 648 - 400 + 600 @@ -58,9 +58,9 @@ 0 - -130 + 0 603 - 812 + 694 @@ -78,15 +78,8 @@ false - - - - - Start Minecraft maximized - - - - + + The base game only supports resolution. In order to simulate the maximized behaviour the current implementation approximates the maximum display size. @@ -96,111 +89,53 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 6 - - - - - - + + - &Window Size - - - windowWidthSpinBox + When the game window closes, quit the launcher - - - - - - - 0 - 0 - - - - - - - 1 - - - 65536 - - - 480 - - - - - - - × - - - - - - - - 0 - 0 - - - - - - - 1 - - - 65536 - - - 1 - - - 854 - - - - - - - pixels - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Start Minecraft maximized + + - + + + + When the game window opens, hide the launcher + + + + + + + + 0 + 0 + + + + + + + 1 + + + 65536 + + + 1 + + + 854 + + + + Qt::Vertical @@ -216,20 +151,65 @@ - - - - When the game window opens, hide the launcher + + + + + 0 + 0 + + + + + + + 1 + + + 65536 + + + 480 - - + + - When the game window closes, quit the launcher + &Window Size + + + windowWidthSpinBox + + + + × + + + + + + + pixels + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + @@ -329,15 +309,9 @@ false - + - - - 0 - 0 - - Account @@ -353,6 +327,19 @@ + + + + Qt::Horizontal + + + + 0 + 0 + + + + @@ -367,15 +354,32 @@ false - - + + + + + + 0 + 0 + + + + + + + + Singleplayer world + + + + Server address - + @@ -385,22 +389,12 @@ - - - - Singleplayer world + + + + Qt::Horizontal - - - - - - - 0 - 0 - - - + @@ -440,7 +434,7 @@ 0 0 624 - 287 + 487 @@ -463,8 +457,8 @@ 0 0 - 603 - 470 + 624 + 487 @@ -507,15 +501,11 @@ false - - - - - Use system installation of OpenAL - - - - + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + &GLFW library path @@ -525,31 +515,7 @@ - - - - false - - - - - - - Use system installation of GLFW - - - - - - - &OpenAL library path - - - lineEditOpenALPath - - - - + Qt::Vertical @@ -565,13 +531,44 @@ - + + + + &OpenAL library path + + + lineEditOpenALPath + + + + false + + + + Use system installation of GLFW + + + + + + + Use system installation of OpenAL + + + + + + + false + + + @@ -715,7 +712,6 @@ javaScrollArea scrollArea_2 onlineFixes - useNativeGLFWCheck useNativeOpenALCheck perfomanceGroupBox enableFeralGamemodeCheck diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui deleted file mode 100644 index 3e2808a48..000000000 --- a/launcher/ui/widgets/ThemeCustomizationWidget.ui +++ /dev/null @@ -1,171 +0,0 @@ - - - ThemeCustomizationWidget - - - - 0 - 0 - 400 - 168 - - - - Form - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - &Widgets - - - widgetStyleComboBox - - - - - - - View widget themes folder. - - - Open Folder - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - View icon themes folder. - - - Open Folder - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - C&at - - - backgroundCatComboBox - - - - - - - &Icons - - - iconsComboBox - - - - - - - View cat packs folder. - - - Open Folder - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - The cat appears in the background and is not shown by default. It is only made visible when pressing the Cat button in the Toolbar. - - - - - - - Refresh All - - - - - - - iconsComboBox - iconsFolder - widgetStyleComboBox - widgetStyleFolder - backgroundCatComboBox - catPackFolder - - - - From 0b3b9debd8d86797b721fa597b409e35380c9140 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 19:42:46 +0100 Subject: [PATCH 45/62] Fix PageDialog OK button Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 27 ++++++++++++++++++++------- launcher/ui/pagedialog/PageDialog.h | 2 ++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index aad204979..6292beec3 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -56,13 +56,26 @@ PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidge restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } -void PageDialog::closeEvent([[maybe_unused]] QCloseEvent* event) +void PageDialog::accept() +{ + if (handleClose()) + QDialog::accept(); +} + +void PageDialog::closeEvent(QCloseEvent* event) +{ + if (handleClose()) + QDialog::closeEvent(event); +} + +bool PageDialog::handleClose() const { qDebug() << "Paged dialog close requested"; - if (m_container->prepareToClose()) { - qDebug() << "Paged dialog close approved"; - APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); - qDebug() << "Paged dialog geometry saved"; - QDialog::closeEvent(event); - } + if (!m_container->prepareToClose()) + return false; + + qDebug() << "Paged dialog close approved"; + APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); + qDebug() << "Paged dialog geometry saved"; + return true; } diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index cc250af75..f3b914923 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -29,7 +29,9 @@ class PageDialog : public QDialog { void applied(); private: + void accept() override; void closeEvent(QCloseEvent* event) override; + bool handleClose() const; private: PageContainer* m_container; From fc94bb6af3f8e79bb7c0d9a6fb58edb75e9143d8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 19:42:54 +0100 Subject: [PATCH 46/62] Add colons to single-line settings Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 36 ++++++++++++------- launcher/ui/pages/global/ProxyPage.ui | 4 +-- launcher/ui/widgets/AppearanceWidget.ui | 26 +++++++++++--- launcher/ui/widgets/JavaSettingsWidget.ui | 6 ++-- .../ui/widgets/MinecraftSettingsWidget.ui | 12 +++---- 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 22ac6a018..b8530a609 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -41,7 +41,7 @@ 0 - -356 + -300 742 1148 @@ -208,6 +208,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -241,7 +247,7 @@ - &Java + &Java: javaDirTextBox @@ -258,7 +264,7 @@ - &Skins + &Skins: skinsDirTextBox @@ -268,7 +274,7 @@ - &Mods + &Mods: modsDirTextBox @@ -285,7 +291,7 @@ - &Downloads + &Downloads: downloadsDirTextBox @@ -301,7 +307,7 @@ - I&nstances + I&nstances: instDirTextBox @@ -341,7 +347,7 @@ - &Icons + &Icons: iconsDirTextBox @@ -438,7 +444,7 @@ - Log History &Limit + Log History &Limit: lineLimitSpinBox @@ -546,14 +552,14 @@ - Retry Limit + Retry Limit: - Concurrent Download Limit + Concurrent Download Limit: @@ -563,7 +569,7 @@ Seconds to wait until the requests are terminated - HTTP Timeout + HTTP Timeout: @@ -589,7 +595,7 @@ - Concurrent Task Limit + Concurrent Task Limit: @@ -598,6 +604,12 @@ Qt::Horizontal + + + 0 + 0 + + diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 3042a4bba..0cbe894e8 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -157,7 +157,7 @@ - &Username + &Username: proxyUserEdit @@ -170,7 +170,7 @@ - &Password + &Password: proxyPassEdit diff --git a/launcher/ui/widgets/AppearanceWidget.ui b/launcher/ui/widgets/AppearanceWidget.ui index d56e6f031..886ac984a 100644 --- a/launcher/ui/widgets/AppearanceWidget.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -61,7 +61,7 @@ - &Cat Pack + &Cat Pack: catPackComboBox @@ -113,7 +113,7 @@ - Theme + Theme: widgetStyleComboBox @@ -123,7 +123,7 @@ - &Icons + &Icons: iconsComboBox @@ -146,7 +146,7 @@ - Console Font + Console Font: @@ -177,6 +177,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -264,6 +270,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -526,6 +538,12 @@ Qt::Horizontal + + + 0 + 0 + + diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 027b20d2f..743c71a13 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -299,7 +299,7 @@ - &PermGen Size + &PermGen Size: permGenSpinBox @@ -316,7 +316,7 @@ - Ma&ximum Memory + Ma&ximum Memory Usage: maxMemSpinBox @@ -326,7 +326,7 @@ - M&inimum Memory + M&inimum Memory Usage: minMemSpinBox diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index 9a9adb8b7..73dbfcad9 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -176,7 +176,7 @@ - &Window Size + &Window Size: windowWidthSpinBox @@ -313,7 +313,7 @@ - Account + Account: @@ -368,14 +368,14 @@ - Singleplayer world + Singleplayer world: - Server address + Server address: @@ -508,7 +508,7 @@ - &GLFW library path + &GLFW library path: lineEditGLFWPath @@ -534,7 +534,7 @@ - &OpenAL library path + &OpenAL library path: lineEditOpenALPath From 6d3d4d0083d7c92e0faccde58836ae9812f9da9e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 15 Apr 2025 19:52:21 +0100 Subject: [PATCH 47/62] Redo tab orderings Signed-off-by: TheKodeToad --- launcher/ui/pages/global/LauncherPage.ui | 28 ++++++++++++++++++- launcher/ui/pages/global/ProxyPage.ui | 10 +++++++ launcher/ui/widgets/AppearanceWidget.ui | 3 ++ launcher/ui/widgets/JavaSettingsWidget.ui | 10 +++++-- .../ui/widgets/MinecraftSettingsWidget.ui | 25 +++++++++++++---- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index b8530a609..55478e6a0 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -41,7 +41,7 @@ 0 - -300 + -356 742 1148 @@ -636,9 +636,35 @@ scrollArea + sortByNameBtn + sortLastLaunchedBtn + renamingBehaviorComboBox + preferMenuBarCheckBox autoUpdateCheckBox + updateIntervalSpinBox + instDirTextBox + instDirBrowseBtn + modsDirTextBox + modsDirBrowseBtn + iconsDirTextBox + iconsDirBrowseBtn + javaDirTextBox + javaDirBrowseBtn + skinsDirTextBox + skinsDirBrowseBtn + downloadsDirTextBox + downloadsDirBrowseBtn + downloadsDirWatchRecursiveCheckBox + downloadsDirMoveCheckBox metadataEnableBtn dependenciesEnableBtn + modpackUpdatePromptBtn + lineLimitSpinBox + checkStopLogging + numberOfConcurrentTasksSpinBox + numberOfConcurrentDownloadsSpinBox + numberOfManualRetriesSpinBox + timeoutSecondsSpinBox diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 0cbe894e8..dec8d0a26 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -212,6 +212,16 @@ + + proxyDefaultBtn + proxyNoneBtn + proxySOCKS5Btn + proxyHTTPBtn + proxyAddrEdit + proxyPortEdit + proxyUserEdit + proxyPassEdit + diff --git a/launcher/ui/widgets/AppearanceWidget.ui b/launcher/ui/widgets/AppearanceWidget.ui index 886ac984a..c672279f0 100644 --- a/launcher/ui/widgets/AppearanceWidget.ui +++ b/launcher/ui/widgets/AppearanceWidget.ui @@ -584,7 +584,10 @@ catPackComboBox catPackFolder reloadThemesButton + consoleFont + fontSizeBox catOpacitySlider + consolePreview diff --git a/launcher/ui/widgets/JavaSettingsWidget.ui b/launcher/ui/widgets/JavaSettingsWidget.ui index 743c71a13..fb974570f 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.ui +++ b/launcher/ui/widgets/JavaSettingsWidget.ui @@ -373,12 +373,18 @@ - javaTestBtn - javaDownloadBtn + javaPathTextBox + javaDetectBtn + javaBrowseBtn skipCompatibilityCheckBox skipWizardCheckBox autodetectJavaCheckBox autodownloadJavaCheckBox + javaTestBtn + javaDownloadBtn + minMemSpinBox + maxMemSpinBox + permGenSpinBox jvmArgsTextBox diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index 73dbfcad9..ed12604fd 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -58,7 +58,7 @@ 0 - 0 + -207 603 694 @@ -702,24 +702,37 @@ openGlobalSettingsButton settingsTabs + scrollArea maximizedCheckBox + windowHeightSpinBox + windowWidthSpinBox + closeAfterLaunchCheck + quitAfterGameStopCheck + showConsoleCheck + showConsoleErrorCheck + autoCloseConsoleCheck showGameTime recordGameTime showGlobalGameTime showGameTimeWithoutDays - showConsoleCheck - autoCloseConsoleCheck + instanceAccountGroupBox + instanceAccountSelector + serverJoinGroupBox + serverJoinAddressButton + serverJoinAddress + worldJoinButton + worldsCb javaScrollArea scrollArea_2 onlineFixes + useNativeGLFWCheck + lineEditGLFWPath useNativeOpenALCheck - perfomanceGroupBox + lineEditOpenALPath enableFeralGamemodeCheck enableMangoHud useDiscreteGpuCheck useZink - serverJoinAddressButton - worldJoinButton From 9b815e8bee967b554d26e9489c92b8bb57012cf8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 16 Apr 2025 11:54:31 +0100 Subject: [PATCH 48/62] Emit applied (oops) Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 6292beec3..79bcb5701 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -77,5 +77,7 @@ bool PageDialog::handleClose() const qDebug() << "Paged dialog close approved"; APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; + + emit applied(); return true; } From 77f53c02a9fdb79bbccfc7159607b49ad7abf0dd Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 18 Apr 2025 16:58:34 +0100 Subject: [PATCH 49/62] Fix compilation Signed-off-by: TheKodeToad --- launcher/ui/pagedialog/PageDialog.cpp | 2 +- launcher/ui/pagedialog/PageDialog.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 79bcb5701..8ce53448a 100644 --- a/launcher/ui/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -68,7 +68,7 @@ void PageDialog::closeEvent(QCloseEvent* event) QDialog::closeEvent(event); } -bool PageDialog::handleClose() const +bool PageDialog::handleClose() { qDebug() << "Paged dialog close requested"; if (!m_container->prepareToClose()) diff --git a/launcher/ui/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index f3b914923..9a8a3ccaa 100644 --- a/launcher/ui/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -31,7 +31,7 @@ class PageDialog : public QDialog { private: void accept() override; void closeEvent(QCloseEvent* event) override; - bool handleClose() const; + bool handleClose(); private: PageContainer* m_container; From d3f337d6ef3f6e824d13a7ab8d160b42c59228f8 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 08:13:10 +0800 Subject: [PATCH 50/62] Delete shortcut when deleting instances Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 11 ++++ launcher/BaseInstance.h | 17 +++++ launcher/FileSystem.cpp | 32 ++++----- launcher/FileSystem.h | 3 +- launcher/InstanceList.cpp | 69 +++++++++++++++++--- launcher/InstanceList.h | 10 ++- launcher/minecraft/ShortcutUtils.cpp | 59 ++++++++++------- launcher/minecraft/ShortcutUtils.h | 10 +-- launcher/ui/MainWindow.cpp | 7 +- launcher/ui/dialogs/CreateShortcutDialog.cpp | 14 ++-- launcher/ui/dialogs/CreateShortcutDialog.h | 3 - 11 files changed, 168 insertions(+), 67 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 70e0f9dc1..1aa01568c 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -398,6 +398,17 @@ bool BaseInstance::syncInstanceDirName(const QString& newRoot) const return oldRoot == newRoot || QFile::rename(oldRoot, newRoot); } +void BaseInstance::registerShortcut(const ShortcutData& data) +{ + m_shortcuts.append(data); + qDebug() << "Registering shortcut for instance" << id() << "with name" << data.name << "and path" << data.filePath; +} + +QList& BaseInstance::getShortcuts() +{ + return m_shortcuts; +} + QString BaseInstance::name() const { return m_settings->get("name").toString(); diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 1acf1afe0..d2ff64e7e 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,16 @@ class BaseInstance; // pointer for lazy people using InstancePtr = std::shared_ptr; +/// Shortcut saving target representations +enum class ShortcutTarget { Desktop, Applications, Other }; + +/// Shortcut data representation +struct ShortcutData { + QString name; + QString filePath; + ShortcutTarget target; +}; + /*! * \brief Base class for instances. * This class implements many functions that are common between instances and @@ -129,6 +140,10 @@ class BaseInstance : public QObject, public std::enable_shared_from_this& getShortcuts(); + /// Value used for instance window titles QString windowTitle() const; @@ -308,6 +323,8 @@ class BaseInstance : public QObject, public std::enable_shared_from_this m_shortcuts; }; Q_DECLARE_METATYPE(shared_qobject_ptr) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 9d45f4af3..c5386a43b 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -898,26 +898,26 @@ QString getApplicationsDir() } // Cross-platform Shortcut creation -bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) +QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) { if (destination.isEmpty()) { destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); } if (!ensureFilePathExists(destination)) { qWarning() << "Destination path can't be created!"; - return false; + return ""; } #if defined(Q_OS_MACOS) QDir application = destination + ".app/"; if (application.exists()) { qWarning() << "Application already exists!"; - return false; + return ""; } if (!application.mkpath(".")) { qWarning() << "Couldn't create application"; - return false; + return ""; } QDir content = application.path() + "/Contents/"; @@ -927,7 +927,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) { qWarning() << "Couldn't create directories within application"; - return false; + return ""; } info.open(QIODevice::WriteOnly | QIODevice::Text); @@ -976,7 +976,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri "\n" ""; - return true; + return application.path(); #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated destination += ".desktop"; @@ -1002,32 +1002,32 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); - return true; + return destination; #elif defined(Q_OS_WIN) QFileInfo targetInfo(target); if (!targetInfo.exists()) { qWarning() << "Target file does not exist!"; - return false; + return ""; } target = targetInfo.absoluteFilePath(); if (target.length() >= MAX_PATH) { qWarning() << "Target file path is too long!"; - return false; + return ""; } if (!icon.isEmpty() && icon.length() >= MAX_PATH) { qWarning() << "Icon path is too long!"; - return false; + return ""; } destination += ".lnk"; if (destination.length() >= MAX_PATH) { qWarning() << "Destination path is too long!"; - return false; + return ""; } QString argStr; @@ -1046,7 +1046,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri if (argStr.length() >= MAX_PATH) { qWarning() << "Arguments string is too long!"; - return false; + return ""; } HRESULT hres; @@ -1055,7 +1055,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri hres = CoInitialize(nullptr); if (FAILED(hres)) { qWarning() << "Failed to initialize COM!"; - return false; + return ""; } WCHAR wsz[MAX_PATH]; @@ -1109,10 +1109,12 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri // go away COM, nobody likes you CoUninitialize(); - return SUCCEEDED(hres); + if (SUCCEEDED(hres)) + return destination; + return ""; #else qWarning("Desktop Shortcuts not supported on your platform!"); - return false; + return ""; #endif } diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index b1108eded..83cf41d7f 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -362,8 +362,9 @@ bool overrideFolder(QString overwritten_path, QString override_path); /** * Creates a shortcut to the specified target file at the specified destination path. + * Returns empty string if creation failed; otherwise returns the path to the created shortcut. */ -bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon); +QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon); enum class FilesystemType { FAT, diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 89e7dc04d..ef8be4919 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -60,6 +60,7 @@ #include "NullInstance.h" #include "WatchLock.h" #include "minecraft/MinecraftInstance.h" +#include "minecraft/ShortcutUtils.h" #include "settings/INISettingsObject.h" #ifdef Q_OS_WIN32 @@ -333,7 +334,7 @@ bool InstanceList::trashInstance(const InstanceId& id) { auto inst = getInstanceById(id); if (!inst) { - qDebug() << "Cannot trash instance" << id << ". No such instance is present (deleted externally?)."; + qWarning() << "Cannot trash instance" << id << ". No such instance is present (deleted externally?)."; return false; } @@ -348,26 +349,48 @@ bool InstanceList::trashInstance(const InstanceId& id) } if (!FS::trash(inst->instanceRoot(), &trashedLoc)) { - qDebug() << "Trash of instance" << id << "has not been completely successfully..."; + qWarning() << "Trash of instance" << id << "has not been completely successful..."; return false; } qDebug() << "Instance" << id << "has been trashed by the launcher."; m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId }); + // Also trash all of its shortcuts; we remove the shortcuts if trash fails since it is invalid anyway + auto& shortcuts = inst->getShortcuts(); + for (auto it = shortcuts.begin(); it != shortcuts.end();) { + const auto& [name, filePath, target] = *it; + if (!FS::trash(filePath, &trashedLoc)) { + qWarning() << "Trash of shortcut" << name << "at path" << filePath << "for instance" << id + << "has not been successful, trying to delete it instead..."; + if (!FS::deletePath(filePath)) { + qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id + << "has not been successful, given up..."; + ++it; + } else { + qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher."; + it = shortcuts.erase(it); + } + continue; + } + qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been trashed by the launcher."; + m_trashHistory.top().shortcuts.append({ *it, trashedLoc }); + it = shortcuts.erase(it); + } + return true; } -bool InstanceList::trashedSomething() +bool InstanceList::trashedSomething() const { return !m_trashHistory.empty(); } -void InstanceList::undoTrashInstance() +bool InstanceList::undoTrashInstance() { if (m_trashHistory.empty()) { qWarning() << "Nothing to recover from trash."; - return; + return true; } auto top = m_trashHistory.pop(); @@ -377,21 +400,41 @@ void InstanceList::undoTrashInstance() top.path += "1"; } + if (!QFile(top.trashPath).rename(top.path)) { + qWarning() << "Moving" << top.trashPath << "back to" << top.path << "failed!"; + return false; + } qDebug() << "Moving" << top.trashPath << "back to" << top.path; - QFile(top.trashPath).rename(top.path); + + bool ok = true; + for (const auto& [data, trashPath] : top.shortcuts) { + if (QDir(data.filePath).exists()) { + // Don't try to append 1 here as the shortcut may have suffixes like .app, just warn and skip it + qWarning() << "Shortcut" << trashPath << "original directory" << data.filePath << "already exists!"; + ok = false; + continue; + } + if (!QFile(trashPath).rename(data.filePath)) { + qWarning() << "Moving shortcut from" << trashPath << "back to" << data.filePath << "failed!"; + ok = false; + continue; + } + qDebug() << "Moving shortcut from" << trashPath << "back to" << data.filePath; + } m_instanceGroupIndex[top.id] = top.groupName; increaseGroupCount(top.groupName); saveGroupList(); emit instancesChanged(); + return ok; } void InstanceList::deleteInstance(const InstanceId& id) { auto inst = getInstanceById(id); if (!inst) { - qDebug() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?)."; + qWarning() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?)."; return; } @@ -404,11 +447,19 @@ void InstanceList::deleteInstance(const InstanceId& id) qDebug() << "Will delete instance" << id; if (!FS::deletePath(inst->instanceRoot())) { - qWarning() << "Deletion of instance" << id << "has not been completely successful ..."; + qWarning() << "Deletion of instance" << id << "has not been completely successful..."; return; } qDebug() << "Instance" << id << "has been deleted by the launcher."; + + for (const auto& [name, filePath, target] : inst->getShortcuts()) { + if (!FS::deletePath(filePath)) { + qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful..."; + continue; + } + qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher."; + } } static QMap getIdMapping(const QList& list) @@ -638,7 +689,7 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) } else { inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); } - qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot(); + qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot(); return inst; } diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h index c85fe55c7..fc4fa9a39 100644 --- a/launcher/InstanceList.h +++ b/launcher/InstanceList.h @@ -56,11 +56,17 @@ enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateErro enum class GroupsState { NotLoaded, Steady, Dirty }; +struct TrashShortcutItem { + ShortcutData data; + QString trashPath; +}; + struct TrashHistoryItem { QString id; QString path; QString trashPath; QString groupName; + QList shortcuts; }; class InstanceList : public QAbstractListModel { @@ -111,8 +117,8 @@ class InstanceList : public QAbstractListModel { void deleteGroup(const GroupId& name); void renameGroup(const GroupId& src, const GroupId& dst); bool trashInstance(const InstanceId& id); - bool trashedSomething(); - void undoTrashInstance(); + bool trashedSomething() const; + bool undoTrashInstance(); void deleteInstance(const InstanceId& id); // Wrap an instance creation task in some more task machinery and make it ready to be used diff --git a/launcher/minecraft/ShortcutUtils.cpp b/launcher/minecraft/ShortcutUtils.cpp index 43954aa6a..0336a9512 100644 --- a/launcher/minecraft/ShortcutUtils.cpp +++ b/launcher/minecraft/ShortcutUtils.cpp @@ -48,10 +48,10 @@ namespace ShortcutUtils { -void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) +bool createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) { if (!shortcut.instance) - return; + return false; QString appPath = QApplication::applicationFilePath(); auto icon = APPLICATION->icons()->icon(shortcut.iconKey.isEmpty() ? shortcut.instance->iconKey() : shortcut.iconKey); @@ -64,7 +64,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) if (appPath.startsWith("/private/var/")) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; + return false; } iconPath = FS::PathCombine(shortcut.instance->instanceRoot(), "Icon.icns"); @@ -72,7 +72,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) QFile iconFile(iconPath); if (!iconFile.open(QFile::WriteOnly)) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for application.")); - return; + return false; } QIcon iconObj = icon->icon(); @@ -82,7 +82,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) if (!success) { iconFile.remove(); QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for application.")); - return; + return false; } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (appPath.startsWith("/tmp/.mount_")) { @@ -102,7 +102,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) QFile iconFile(iconPath); if (!iconFile.open(QFile::WriteOnly)) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut.")); - return; + return false; } bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); iconFile.close(); @@ -110,7 +110,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) if (!success) { iconFile.remove(); QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut.")); - return; + return false; } if (DesktopServices::isFlatpak()) { @@ -128,7 +128,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) QFile iconFile(iconPath); if (!iconFile.open(QFile::WriteOnly)) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut.")); - return; + return false; } bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); iconFile.close(); @@ -139,51 +139,58 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath) if (!success) { iconFile.remove(); QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut.")); - return; + return false; } #else QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Not supported on your platform!")); - return; + return false; #endif args.append({ "--launch", shortcut.instance->id() }); args.append(shortcut.extraArgs); - if (!FS::createShortcut(filePath, appPath, args, shortcut.name, iconPath)) { + QString shortcutPath = FS::createShortcut(filePath, appPath, args, shortcut.name, iconPath); + if (shortcutPath.isEmpty()) { #if not defined(Q_OS_MACOS) iconFile.remove(); #endif QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create %1 shortcut!").arg(shortcut.targetString)); + return false; } + + shortcut.instance->registerShortcut({ shortcut.name, shortcutPath, shortcut.target }); + return true; } -void createInstanceShortcutOnDesktop(const Shortcut& shortcut) +bool createInstanceShortcutOnDesktop(const Shortcut& shortcut) { if (!shortcut.instance) - return; + return false; QString desktopDir = FS::getDesktopDir(); if (desktopDir.isEmpty()) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Couldn't find desktop?!")); - return; + return false; } QString shortcutFilePath = FS::PathCombine(desktopDir, FS::RemoveInvalidFilenameChars(shortcut.name)); - createInstanceShortcut(shortcut, shortcutFilePath); + if (!createInstanceShortcut(shortcut, shortcutFilePath)) + return false; QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Created a shortcut to this %1 on your desktop!").arg(shortcut.targetString)); + return true; } -void createInstanceShortcutInApplications(const Shortcut& shortcut) +bool createInstanceShortcutInApplications(const Shortcut& shortcut) { if (!shortcut.instance) - return; + return false; QString applicationsDir = FS::getApplicationsDir(); if (applicationsDir.isEmpty()) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Couldn't find applications folder?!")); - return; + return false; } #if defined(Q_OS_MACOS) || defined(Q_OS_WIN) @@ -193,20 +200,22 @@ void createInstanceShortcutInApplications(const Shortcut& shortcut) if (!applicationsDirQ.mkpath(".")) { QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create instances folder in applications folder!")); - return; + return false; } #endif QString shortcutFilePath = FS::PathCombine(applicationsDir, FS::RemoveInvalidFilenameChars(shortcut.name)); - createInstanceShortcut(shortcut, shortcutFilePath); + if (!createInstanceShortcut(shortcut, shortcutFilePath)) + return false; QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Created a shortcut to this %1 in your applications folder!").arg(shortcut.targetString)); + return true; } -void createInstanceShortcutInOther(const Shortcut& shortcut) +bool createInstanceShortcutInOther(const Shortcut& shortcut) { if (!shortcut.instance) - return; + return false; QString defaultedDir = FS::getDesktopDir(); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) @@ -225,13 +234,15 @@ void createInstanceShortcutInOther(const Shortcut& shortcut) shortcutFilePath = fileDialog.getSaveFileName(shortcut.parent, QObject::tr("Create Shortcut"), shortcutFilePath, QObject::tr("Desktop Entries") + " (*" + extension + ")"); if (shortcutFilePath.isEmpty()) - return; // file dialog canceled by user + return false; // file dialog canceled by user if (shortcutFilePath.endsWith(extension)) shortcutFilePath = shortcutFilePath.mid(0, shortcutFilePath.length() - extension.length()); - createInstanceShortcut(shortcut, shortcutFilePath); + if (!createInstanceShortcut(shortcut, shortcutFilePath)) + return false; QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Created a shortcut to this %1!").arg(shortcut.targetString)); + return true; } } // namespace ShortcutUtils diff --git a/launcher/minecraft/ShortcutUtils.h b/launcher/minecraft/ShortcutUtils.h index e3d2e283a..b995c36bd 100644 --- a/launcher/minecraft/ShortcutUtils.h +++ b/launcher/minecraft/ShortcutUtils.h @@ -38,6 +38,7 @@ #pragma once #include "Application.h" +#include #include namespace ShortcutUtils { @@ -49,18 +50,19 @@ struct Shortcut { QWidget* parent = nullptr; QStringList extraArgs = {}; QString iconKey = ""; + ShortcutTarget target; }; /// Create an instance shortcut on the specified file path -void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath); +bool createInstanceShortcut(const Shortcut& shortcut, const QString& filePath); /// Create an instance shortcut on the desktop -void createInstanceShortcutOnDesktop(const Shortcut& shortcut); +bool createInstanceShortcutOnDesktop(const Shortcut& shortcut); /// Create an instance shortcut in the Applications directory -void createInstanceShortcutInApplications(const Shortcut& shortcut); +bool createInstanceShortcutInApplications(const Shortcut& shortcut); /// Create an instance shortcut in other directories -void createInstanceShortcutInOther(const Shortcut& shortcut); +bool createInstanceShortcutInOther(const Shortcut& shortcut); } // namespace ShortcutUtils diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 63fcc3c9b..4f38a53b3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1207,7 +1207,10 @@ void MainWindow::renameGroup(QString group) void MainWindow::undoTrashInstance() { - APPLICATION->instances()->undoTrashInstance(); + if (!APPLICATION->instances()->undoTrashInstance()) + QMessageBox::warning( + this, tr("Failed to undo trashing instance"), + tr("Some instances and shortcuts could not be restored.\nPlease check your trashbin to manually restore them.")); ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); } @@ -1407,7 +1410,7 @@ void MainWindow::on_actionDeleteInstance_triggered() auto id = m_selectedInstance->id(); auto response = CustomMessageBox::selectable(this, tr("Confirm Deletion"), - tr("You are about to delete \"%1\".\n" + tr("You are about to delete \"%1\" and all of its shortcut(s).\n" "This may be permanent and will completely delete the instance.\n\n" "Are you sure?") .arg(m_selectedInstance->name()), diff --git a/launcher/ui/dialogs/CreateShortcutDialog.cpp b/launcher/ui/dialogs/CreateShortcutDialog.cpp index 278573a22..5cfe33c7f 100644 --- a/launcher/ui/dialogs/CreateShortcutDialog.cpp +++ b/launcher/ui/dialogs/CreateShortcutDialog.cpp @@ -83,12 +83,12 @@ CreateShortcutDialog::CreateShortcutDialog(InstancePtr instance, QWidget* parent QString applicationDir = FS::getApplicationsDir(); if (!desktopDir.isEmpty()) - ui->saveTargetSelectionBox->addItem(tr("Desktop"), QVariant::fromValue(SaveTarget::Desktop)); + ui->saveTargetSelectionBox->addItem(tr("Desktop"), QVariant::fromValue(ShortcutTarget::Desktop)); if (!applicationDir.isEmpty()) - ui->saveTargetSelectionBox->addItem(tr("Applications"), QVariant::fromValue(SaveTarget::Applications)); + ui->saveTargetSelectionBox->addItem(tr("Applications"), QVariant::fromValue(ShortcutTarget::Applications)); } - ui->saveTargetSelectionBox->addItem(tr("Other..."), QVariant::fromValue(SaveTarget::Other)); + ui->saveTargetSelectionBox->addItem(tr("Other..."), QVariant::fromValue(ShortcutTarget::Other)); // Populate worlds if (m_QuickJoinSupported) { @@ -206,17 +206,17 @@ void CreateShortcutDialog::createShortcut() } } - auto target = ui->saveTargetSelectionBox->currentData().value(); + auto target = ui->saveTargetSelectionBox->currentData().value(); auto name = ui->instNameTextBox->text(); if (name.isEmpty()) name = ui->instNameTextBox->placeholderText(); if (ui->overrideAccountCheckbox->isChecked()) extraArgs.append({ "--profile", ui->accountSelectionBox->currentData().toString() }); - ShortcutUtils::Shortcut args{ m_instance.get(), name, targetString, this, extraArgs, InstIconKey }; - if (target == SaveTarget::Desktop) + ShortcutUtils::Shortcut args{ m_instance.get(), name, targetString, this, extraArgs, InstIconKey, target }; + if (target == ShortcutTarget::Desktop) ShortcutUtils::createInstanceShortcutOnDesktop(args); - else if (target == SaveTarget::Applications) + else if (target == ShortcutTarget::Applications) ShortcutUtils::createInstanceShortcutInApplications(args); else ShortcutUtils::createInstanceShortcutInOther(args); diff --git a/launcher/ui/dialogs/CreateShortcutDialog.h b/launcher/ui/dialogs/CreateShortcutDialog.h index cfedbf017..29e68a787 100644 --- a/launcher/ui/dialogs/CreateShortcutDialog.h +++ b/launcher/ui/dialogs/CreateShortcutDialog.h @@ -54,9 +54,6 @@ class CreateShortcutDialog : public QDialog { InstancePtr m_instance; bool m_QuickJoinSupported = false; - // Index representations - enum class SaveTarget { Desktop, Applications, Other }; - // Functions void stateChanged(); }; From 7c3a810d3d6bda55f002bf9224e4df945b9d86e4 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 14:16:40 +0800 Subject: [PATCH 51/62] Implement persistence by storing shortcut in settings Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 15 ++++++++++--- launcher/BaseInstance.h | 20 +++++++++++++---- launcher/InstanceList.cpp | 28 +++++++++++++++++------- launcher/minecraft/MinecraftInstance.cpp | 4 ++++ 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 1aa01568c..2187bc09a 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -69,6 +69,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("lastTimePlayed", 0); m_settings->registerSetting("linkedInstances", "[]"); + m_settings->registerSetting("shortcuts", QVariant::fromValue(QList{})); // Game time override auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false); @@ -400,13 +401,21 @@ bool BaseInstance::syncInstanceDirName(const QString& newRoot) const void BaseInstance::registerShortcut(const ShortcutData& data) { - m_shortcuts.append(data); + auto currentShortcuts = shortcuts(); + currentShortcuts.append(data); qDebug() << "Registering shortcut for instance" << id() << "with name" << data.name << "and path" << data.filePath; + setShortcuts(currentShortcuts); } -QList& BaseInstance::getShortcuts() +void BaseInstance::setShortcuts(const QList& shortcuts) { - return m_shortcuts; + // FIXME: if no change, do not set. setting involves saving a file. + m_settings->set("shortcuts", QVariant::fromValue(shortcuts)); +} + +QList BaseInstance::shortcuts() const +{ + return m_settings->get("shortcuts").value>(); } QString BaseInstance::name() const diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index d2ff64e7e..52aa39067 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -38,6 +38,7 @@ #pragma once #include +#include #include #include #include @@ -74,7 +75,18 @@ enum class ShortcutTarget { Desktop, Applications, Other }; struct ShortcutData { QString name; QString filePath; - ShortcutTarget target; + ShortcutTarget target = ShortcutTarget::Other; + + friend QDataStream& operator<<(QDataStream& out, const ShortcutData& data) + { + out << data.name << data.filePath << data.target; + return out; + } + friend QDataStream& operator>>(QDataStream& in, ShortcutData& data) + { + in >> data.name >> data.filePath >> data.target; + return in; + } }; /*! @@ -142,7 +154,8 @@ class BaseInstance : public QObject, public std::enable_shared_from_this& getShortcuts(); + QList shortcuts() const; + void setShortcuts(const QList& shortcuts); /// Value used for instance window titles QString windowTitle() const; @@ -323,10 +336,9 @@ class BaseInstance : public QObject, public std::enable_shared_from_this m_shortcuts; }; Q_DECLARE_METATYPE(shared_qobject_ptr) +Q_DECLARE_METATYPE(ShortcutData) // Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) // Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index ef8be4919..b98f51d82 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -357,25 +357,20 @@ bool InstanceList::trashInstance(const InstanceId& id) m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId }); // Also trash all of its shortcuts; we remove the shortcuts if trash fails since it is invalid anyway - auto& shortcuts = inst->getShortcuts(); - for (auto it = shortcuts.begin(); it != shortcuts.end();) { - const auto& [name, filePath, target] = *it; + for (const auto& [name, filePath, target] : inst->shortcuts()) { if (!FS::trash(filePath, &trashedLoc)) { qWarning() << "Trash of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful, trying to delete it instead..."; if (!FS::deletePath(filePath)) { qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful, given up..."; - ++it; } else { qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher."; - it = shortcuts.erase(it); } continue; } qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been trashed by the launcher."; - m_trashHistory.top().shortcuts.append({ *it, trashedLoc }); - it = shortcuts.erase(it); + m_trashHistory.top().shortcuts.append({ { name, filePath, target }, trashedLoc }); } return true; @@ -453,7 +448,7 @@ void InstanceList::deleteInstance(const InstanceId& id) qDebug() << "Instance" << id << "has been deleted by the launcher."; - for (const auto& [name, filePath, target] : inst->getShortcuts()) { + for (const auto& [name, filePath, target] : inst->shortcuts()) { if (!FS::deletePath(filePath)) { qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful..."; continue; @@ -675,6 +670,7 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) } auto instanceRoot = FS::PathCombine(m_instDir, id); + qRegisterMetaType>("QList"); auto instanceSettings = std::make_shared(FS::PathCombine(instanceRoot, "instance.cfg")); InstancePtr inst; @@ -690,6 +686,22 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); } qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot(); + + // Fixup the shortcuts by pruning all non-existing links + auto shortcut = inst->shortcuts(); + for (auto it = shortcut.begin(); it != shortcut.end();) { + const auto& [name, filePath, target] = *it; + if (!QDir(filePath).exists()) { + qWarning() << "Shortcut" << name << "have non-existent path" << filePath; + it = shortcut.erase(it); + continue; + } + ++it; + } + inst->setShortcuts(shortcut); + if (!shortcut.isEmpty()) + qDebug() << "Loaded" << shortcut.size() << "shortcut(s) for instance" << inst->name(); + return inst; } diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 635cecfac..72c863bdb 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1040,6 +1040,10 @@ QString MinecraftInstance::getStatusbarDescription() .arg(Time::prettifyDuration(totalTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); } } + auto currentShortcuts = shortcuts(); + if (!currentShortcuts.isEmpty()) { + description.append(tr(", %n shortcut(s) registered", "", currentShortcuts.size())); + } if (hasCrashed()) { description.append(tr(", has crashed.")); } From d2ee023788341237dc6c195ab5facdf1b031315b Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 16:13:16 +0800 Subject: [PATCH 52/62] Switch to JSON-encoded store Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 20 +++++++++++++++++--- launcher/BaseInstance.h | 12 ------------ launcher/InstanceList.cpp | 1 - 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 2187bc09a..8a6060948 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -69,7 +69,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("lastTimePlayed", 0); m_settings->registerSetting("linkedInstances", "[]"); - m_settings->registerSetting("shortcuts", QVariant::fromValue(QList{})); + m_settings->registerSetting("shortcuts", QVariant::fromValue(QByteArray{})); // Game time override auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false); @@ -410,12 +410,26 @@ void BaseInstance::registerShortcut(const ShortcutData& data) void BaseInstance::setShortcuts(const QList& shortcuts) { // FIXME: if no change, do not set. setting involves saving a file. - m_settings->set("shortcuts", QVariant::fromValue(shortcuts)); + QJsonArray array; + for (const auto& elem : shortcuts) { + array.append(QJsonObject{ { "name", elem.name }, { "filePath", elem.filePath }, { "target", static_cast(elem.target) } }); + } + + QJsonDocument document; + document.setArray(array); + m_settings->set("shortcuts", QVariant::fromValue(document.toJson(QJsonDocument::Compact))); } QList BaseInstance::shortcuts() const { - return m_settings->get("shortcuts").value>(); + auto data = m_settings->get("shortcuts").value(); + auto document = QJsonDocument::fromJson(data); + QList results; + for (const auto& elem : document.array()) { + auto dict = elem.toObject(); + results.append({ dict["name"].toString(), dict["filePath"].toString(), static_cast(dict["target"].toInt()) }); + } + return results; } QString BaseInstance::name() const diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 52aa39067..3509c0155 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -76,17 +76,6 @@ struct ShortcutData { QString name; QString filePath; ShortcutTarget target = ShortcutTarget::Other; - - friend QDataStream& operator<<(QDataStream& out, const ShortcutData& data) - { - out << data.name << data.filePath << data.target; - return out; - } - friend QDataStream& operator>>(QDataStream& in, ShortcutData& data) - { - in >> data.name >> data.filePath >> data.target; - return in; - } }; /*! @@ -339,6 +328,5 @@ class BaseInstance : public QObject, public std::enable_shared_from_this) -Q_DECLARE_METATYPE(ShortcutData) // Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) // Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index b98f51d82..f6512b25d 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -670,7 +670,6 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) } auto instanceRoot = FS::PathCombine(m_instDir, id); - qRegisterMetaType>("QList"); auto instanceSettings = std::make_shared(FS::PathCombine(instanceRoot, "instance.cfg")); InstancePtr inst; From 1c69f6335747ebec171245c62340eaa4002b1e66 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 1 Jun 2025 09:15:21 +0100 Subject: [PATCH 53/62] Hopefully fix segfault with HintOverrideProxyStyle Signed-off-by: TheKodeToad --- launcher/ui/themes/HintOverrideProxyStyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/themes/HintOverrideProxyStyle.cpp b/launcher/ui/themes/HintOverrideProxyStyle.cpp index f5b8232a8..1a044ae70 100644 --- a/launcher/ui/themes/HintOverrideProxyStyle.cpp +++ b/launcher/ui/themes/HintOverrideProxyStyle.cpp @@ -20,7 +20,7 @@ HintOverrideProxyStyle::HintOverrideProxyStyle(QStyle* style) : QProxyStyle(style) { - setObjectName(style->objectName()); + setObjectName(baseStyle()->objectName()); } int HintOverrideProxyStyle::styleHint(QStyle::StyleHint hint, From 4214571cffaf0754a90b208c196a549e9bef7f95 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 16:18:35 +0800 Subject: [PATCH 54/62] Add # of shortcuts to deletion confirmation screen instead Signed-off-by: Yihe Li --- launcher/minecraft/MinecraftInstance.cpp | 4 ---- launcher/ui/MainWindow.cpp | 8 ++++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 72c863bdb..635cecfac 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1040,10 +1040,6 @@ QString MinecraftInstance::getStatusbarDescription() .arg(Time::prettifyDuration(totalTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); } } - auto currentShortcuts = shortcuts(); - if (!currentShortcuts.isEmpty()) { - description.append(tr(", %n shortcut(s) registered", "", currentShortcuts.size())); - } if (hasCrashed()) { description.append(tr(", has crashed.")); } diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 4f38a53b3..88724d788 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1409,11 +1409,15 @@ void MainWindow::on_actionDeleteInstance_triggered() } auto id = m_selectedInstance->id(); + QString shortcutStr; + auto shortcuts = m_selectedInstance->shortcuts(); + if (!shortcuts.isEmpty()) + shortcutStr = tr(" and its %n registered shortcut(s)", "", shortcuts.size()); auto response = CustomMessageBox::selectable(this, tr("Confirm Deletion"), - tr("You are about to delete \"%1\" and all of its shortcut(s).\n" + tr("You are about to delete \"%1\"%2.\n" "This may be permanent and will completely delete the instance.\n\n" "Are you sure?") - .arg(m_selectedInstance->name()), + .arg(m_selectedInstance->name(), shortcutStr), QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ->exec(); From d9884f0d0365a19f7d41792aed6d57540f7fa853 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 16:33:43 +0800 Subject: [PATCH 55/62] Add notes in shortcut creation screen Signed-off-by: Yihe Li --- launcher/ui/dialogs/CreateShortcutDialog.ui | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/launcher/ui/dialogs/CreateShortcutDialog.ui b/launcher/ui/dialogs/CreateShortcutDialog.ui index 9e2bdd747..24d4dc2dc 100644 --- a/launcher/ui/dialogs/CreateShortcutDialog.ui +++ b/launcher/ui/dialogs/CreateShortcutDialog.ui @@ -194,6 +194,20 @@ + + + + Note: If a shortcut is moved after creation, it won't be deleted when deleting the instance. + + + + + + + You'll need to delete them manually if that is the case. + + + From caff4b884f7037f646bedac59da01fcd4340525e Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Sun, 1 Jun 2025 18:31:27 +0800 Subject: [PATCH 56/62] Use null QString instead of empty Signed-off-by: Yihe Li --- launcher/FileSystem.cpp | 24 ++++++++++++------------ launcher/FileSystem.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index c5386a43b..5136e7954 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -905,19 +905,19 @@ QString createShortcut(QString destination, QString target, QStringList args, QS } if (!ensureFilePathExists(destination)) { qWarning() << "Destination path can't be created!"; - return ""; + return QString(); } #if defined(Q_OS_MACOS) QDir application = destination + ".app/"; if (application.exists()) { qWarning() << "Application already exists!"; - return ""; + return QString(); } if (!application.mkpath(".")) { qWarning() << "Couldn't create application"; - return ""; + return QString(); } QDir content = application.path() + "/Contents/"; @@ -927,7 +927,7 @@ QString createShortcut(QString destination, QString target, QStringList args, QS if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) { qWarning() << "Couldn't create directories within application"; - return ""; + return QString(); } info.open(QIODevice::WriteOnly | QIODevice::Text); @@ -1008,26 +1008,26 @@ QString createShortcut(QString destination, QString target, QStringList args, QS if (!targetInfo.exists()) { qWarning() << "Target file does not exist!"; - return ""; + return QString(); } target = targetInfo.absoluteFilePath(); if (target.length() >= MAX_PATH) { qWarning() << "Target file path is too long!"; - return ""; + return QString(); } if (!icon.isEmpty() && icon.length() >= MAX_PATH) { qWarning() << "Icon path is too long!"; - return ""; + return QString(); } destination += ".lnk"; if (destination.length() >= MAX_PATH) { qWarning() << "Destination path is too long!"; - return ""; + return QString(); } QString argStr; @@ -1046,7 +1046,7 @@ QString createShortcut(QString destination, QString target, QStringList args, QS if (argStr.length() >= MAX_PATH) { qWarning() << "Arguments string is too long!"; - return ""; + return QString(); } HRESULT hres; @@ -1055,7 +1055,7 @@ QString createShortcut(QString destination, QString target, QStringList args, QS hres = CoInitialize(nullptr); if (FAILED(hres)) { qWarning() << "Failed to initialize COM!"; - return ""; + return QString(); } WCHAR wsz[MAX_PATH]; @@ -1111,10 +1111,10 @@ QString createShortcut(QString destination, QString target, QStringList args, QS if (SUCCEEDED(hres)) return destination; - return ""; + return QString(); #else qWarning("Desktop Shortcuts not supported on your platform!"); - return ""; + return QString(); #endif } diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index 83cf41d7f..0e573a09e 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -362,7 +362,7 @@ bool overrideFolder(QString overwritten_path, QString override_path); /** * Creates a shortcut to the specified target file at the specified destination path. - * Returns empty string if creation failed; otherwise returns the path to the created shortcut. + * Returns null QString if creation failed; otherwise returns the path to the created shortcut. */ QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon); From 49dc9a5d3f76ce36e779805cb38c89b6b5efc3d5 Mon Sep 17 00:00:00 2001 From: Puqns67 Date: Mon, 2 Jun 2025 00:56:07 +0800 Subject: [PATCH 57/62] chore(deps): try find system wide qrcodegencpp-cmake and use it Signed-off-by: Puqns67 --- CMakeLists.txt | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce3d433fb..e3d60a102 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -338,6 +338,9 @@ if(NOT Launcher_FORCE_BUNDLED_LIBS) # Find cmark find_package(cmark QUIET) + + # Find qrcodegencpp-cmake + find_package(qrcodegencpp QUIET) endif() include(ECMQtDeclareLoggingCategory) @@ -528,19 +531,22 @@ if(NOT cmark_FOUND) else() message(STATUS "Using system cmark") endif() +if(NOT qrcodegencpp_FOUND) + set(QRCODE_SOURCES + libraries/qrcodegenerator/cpp/qrcodegen.cpp + libraries/qrcodegenerator/cpp/qrcodegen.hpp + ) + add_library(qrcodegenerator STATIC ${QRCODE_SOURCES}) + target_include_directories(qrcodegenerator PUBLIC "libraries/qrcodegenerator/cpp/" ) + generate_export_header(qrcodegenerator) +else() + add_library(qrcodegenerator ALIAS qrcodegencpp::qrcodegencpp) + message(STATUS "Using system qrcodegencpp-cmake") +endif() add_subdirectory(libraries/gamemode) add_subdirectory(libraries/murmur2) # Hash for usage with the CurseForge API add_subdirectory(libraries/qdcss) # css parser -# qr code generator -set(QRCODE_SOURCES - libraries/qrcodegenerator/cpp/qrcodegen.cpp - libraries/qrcodegenerator/cpp/qrcodegen.hpp -) -add_library(qrcodegenerator STATIC ${QRCODE_SOURCES}) -target_include_directories(qrcodegenerator PUBLIC "libraries/qrcodegenerator/cpp/" ) -generate_export_header(qrcodegenerator) - ############################### Built Artifacts ############################### add_subdirectory(buildconfig) From 0a1001ee84db35e0d58c5caac7a0c9bbea738932 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Mon, 2 Jun 2025 01:34:24 +0800 Subject: [PATCH 58/62] Use QString instead of QByteArray Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 8a6060948..3b4612c73 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -69,7 +69,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("lastTimePlayed", 0); m_settings->registerSetting("linkedInstances", "[]"); - m_settings->registerSetting("shortcuts", QVariant::fromValue(QByteArray{})); + m_settings->registerSetting("shortcuts", QString()); // Game time override auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false); @@ -417,12 +417,12 @@ void BaseInstance::setShortcuts(const QList& shortcuts) QJsonDocument document; document.setArray(array); - m_settings->set("shortcuts", QVariant::fromValue(document.toJson(QJsonDocument::Compact))); + m_settings->set("shortcuts", QString::fromUtf8(document.toJson(QJsonDocument::Compact))); } QList BaseInstance::shortcuts() const { - auto data = m_settings->get("shortcuts").value(); + auto data = m_settings->get("shortcuts").toString().toUtf8(); auto document = QJsonDocument::fromJson(data); QList results; for (const auto& elem : document.array()) { From 50fb2db7184344b87ea0d0070d374e90361f6721 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Mon, 2 Jun 2025 07:36:53 +0800 Subject: [PATCH 59/62] Validate JSON parsing results Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 14 +++++++++++++- launcher/InstanceList.cpp | 11 ----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 3b4612c73..aa7812649 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -427,7 +427,19 @@ QList BaseInstance::shortcuts() const QList results; for (const auto& elem : document.array()) { auto dict = elem.toObject(); - results.append({ dict["name"].toString(), dict["filePath"].toString(), static_cast(dict["target"].toInt()) }); + if (!dict.contains("name") || !dict.contains("filePath") || !dict.contains("target")) + return {}; + int value = dict["target"].toInt(-1); + if (!dict["name"].isString() || !dict["filePath"].isString() || value < 0 || value >= 3) + return {}; + + QString shortcutName = dict["name"].toString(); + QString filePath = dict["filePath"].toString(); + if (!QDir(filePath).exists()) { + qWarning() << "Shortcut" << shortcutName << "for instance" << name() << "have non-existent path" << filePath; + continue; + } + results.append({ shortcutName, filePath, static_cast(value) }); } return results; } diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index f6512b25d..de94db7c3 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -686,18 +686,7 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) } qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot(); - // Fixup the shortcuts by pruning all non-existing links auto shortcut = inst->shortcuts(); - for (auto it = shortcut.begin(); it != shortcut.end();) { - const auto& [name, filePath, target] = *it; - if (!QDir(filePath).exists()) { - qWarning() << "Shortcut" << name << "have non-existent path" << filePath; - it = shortcut.erase(it); - continue; - } - ++it; - } - inst->setShortcuts(shortcut); if (!shortcut.isEmpty()) qDebug() << "Loaded" << shortcut.size() << "shortcut(s) for instance" << inst->name(); From 8965200384936ffb2cc5f5d4fe3c7705bf286413 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Mon, 2 Jun 2025 14:15:30 +0800 Subject: [PATCH 60/62] Handle JSON parse error Signed-off-by: Yihe Li --- launcher/BaseInstance.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index aa7812649..096052a45 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -423,15 +423,21 @@ void BaseInstance::setShortcuts(const QList& shortcuts) QList BaseInstance::shortcuts() const { auto data = m_settings->get("shortcuts").toString().toUtf8(); - auto document = QJsonDocument::fromJson(data); + QJsonParseError parseError; + auto document = QJsonDocument::fromJson(data, &parseError); + if (parseError.error != QJsonParseError::NoError || !document.isArray()) + return {}; + QList results; for (const auto& elem : document.array()) { + if (!elem.isObject()) + continue; auto dict = elem.toObject(); if (!dict.contains("name") || !dict.contains("filePath") || !dict.contains("target")) - return {}; + continue; int value = dict["target"].toInt(-1); if (!dict["name"].isString() || !dict["filePath"].isString() || value < 0 || value >= 3) - return {}; + continue; QString shortcutName = dict["name"].toString(); QString filePath = dict["filePath"].toString(); From 492769aea6e78087e5e3f2524884ba3c9f2b59e1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Apr 2025 19:59:35 +0300 Subject: [PATCH 61/62] feat: add setting to control the loaders for mod search Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 4 ++ .../ui/widgets/MinecraftSettingsWidget.cpp | 61 +++++++++++++++- launcher/ui/widgets/MinecraftSettingsWidget.h | 2 + .../ui/widgets/MinecraftSettingsWidget.ui | 70 +++++++++++++++++-- launcher/ui/widgets/ModFilterWidget.cpp | 9 ++- 5 files changed, 136 insertions(+), 10 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 635cecfac..90c066fe3 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -250,6 +250,10 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerSetting("ExportOptionalFiles", true); m_settings->registerSetting("ExportRecommendedRAM"); + // Join server on launch, this does not have a global override + m_settings->registerSetting("OverrideModDownloadLoaders", false); + m_settings->registerSetting("ModDownloadLoaders", QStringList()); + qDebug() << "Instance-type specific settings were loaded!"; setSpecificSettingsLoaded(true); diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.cpp b/launcher/ui/widgets/MinecraftSettingsWidget.cpp index c3d342d42..637e34db7 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.cpp +++ b/launcher/ui/widgets/MinecraftSettingsWidget.cpp @@ -39,6 +39,7 @@ #include "Application.h" #include "BuildConfig.h" +#include "minecraft/PackProfile.h" #include "minecraft/WorldList.h" #include "minecraft/auth/AccountList.h" #include "settings/Setting.h" @@ -55,6 +56,7 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance, m_ui->openGlobalSettingsButton->setVisible(false); m_ui->instanceAccountGroupBox->hide(); m_ui->serverJoinGroupBox->hide(); + m_ui->loaderGroup->hide(); } else { m_javaSettings = new JavaSettingsWidget(m_instance, this); m_ui->javaScrollArea->setWidget(m_javaSettings); @@ -93,6 +95,17 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance, connect(m_ui->openGlobalSettingsButton, &QCommandLinkButton::clicked, this, &MinecraftSettingsWidget::openGlobalSettings); connect(m_ui->serverJoinAddressButton, &QAbstractButton::toggled, m_ui->serverJoinAddress, &QWidget::setEnabled); connect(m_ui->worldJoinButton, &QAbstractButton::toggled, m_ui->worldsCb, &QWidget::setEnabled); + + connect(m_ui->loaderGroup, &QGroupBox::toggled, this, [this](bool value) { + m_instance->settings()->set("OverrideModDownloadLoaders", value); + if (!value) + m_instance->settings()->reset("ModDownloadLoaders"); + }); + connect(m_ui->neoForge, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged); + connect(m_ui->forge, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged); + connect(m_ui->fabric, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged); + connect(m_ui->quilt, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged); + connect(m_ui->liteLoader, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged); } m_ui->maximizedWarning->hide(); @@ -220,6 +233,35 @@ void MinecraftSettingsWidget::loadSettings() m_ui->instanceAccountGroupBox->setChecked(settings->get("UseAccountForInstance").toBool()); updateAccountsMenu(*settings); + + m_ui->loaderGroup->blockSignals(true); + m_ui->neoForge->blockSignals(true); + m_ui->forge->blockSignals(true); + m_ui->fabric->blockSignals(true); + m_ui->quilt->blockSignals(true); + m_ui->liteLoader->blockSignals(true); + auto instLoaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); + m_ui->loaderGroup->setChecked(settings->get("OverrideModDownloadLoaders").toBool()); + auto loaders = settings->get("ModDownloadLoaders").toStringList(); + if (loaders.isEmpty()) { + m_ui->neoForge->setChecked(instLoaders & ModPlatform::NeoForge); + m_ui->forge->setChecked(instLoaders & ModPlatform::Forge); + m_ui->fabric->setChecked(instLoaders & ModPlatform::Fabric); + m_ui->quilt->setChecked(instLoaders & ModPlatform::Quilt); + m_ui->liteLoader->setChecked(instLoaders & ModPlatform::LiteLoader); + } else { + m_ui->neoForge->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::NeoForge))); + m_ui->forge->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Forge))); + m_ui->fabric->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Fabric))); + m_ui->quilt->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Quilt))); + m_ui->liteLoader->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::LiteLoader))); + } + m_ui->loaderGroup->blockSignals(false); + m_ui->neoForge->blockSignals(false); + m_ui->forge->blockSignals(false); + m_ui->fabric->blockSignals(false); + m_ui->quilt->blockSignals(false); + m_ui->liteLoader->blockSignals(false); } m_ui->legacySettingsGroupBox->setChecked(settings->get("OverrideLegacySettings").toBool()); @@ -238,7 +280,6 @@ void MinecraftSettingsWidget::saveSettings() { SettingsObject::Lock lock(settings); - // Console bool console = m_instance == nullptr || m_ui->consoleSettingsBox->isChecked(); @@ -267,7 +308,7 @@ void MinecraftSettingsWidget::saveSettings() settings->set("LaunchMaximized", m_ui->maximizedCheckBox->isChecked()); settings->set("MinecraftWinWidth", m_ui->windowWidthSpinBox->value()); settings->set("MinecraftWinHeight", m_ui->windowHeightSpinBox->value()); - settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked()); + settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked()); settings->set("QuitAfterGameStop", m_ui->quitAfterGameStopCheck->isChecked()); } else { settings->reset("LaunchMaximized"); @@ -444,3 +485,19 @@ bool MinecraftSettingsWidget::isQuickPlaySupported() { return m_instance->traits().contains("feature:is_quick_play_singleplayer"); } + +void MinecraftSettingsWidget::selectedLoadersChanged() +{ + QStringList loaders; + if (m_ui->neoForge->isChecked()) + loaders << getModLoaderAsString(ModPlatform::NeoForge); + if (m_ui->forge->isChecked()) + loaders << getModLoaderAsString(ModPlatform::Forge); + if (m_ui->fabric->isChecked()) + loaders << getModLoaderAsString(ModPlatform::Fabric); + if (m_ui->quilt->isChecked()) + loaders << getModLoaderAsString(ModPlatform::Quilt); + if (m_ui->liteLoader->isChecked()) + loaders << getModLoaderAsString(ModPlatform::LiteLoader); + m_instance->settings()->set("ModDownloadLoaders", loaders); +} \ No newline at end of file diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.h b/launcher/ui/widgets/MinecraftSettingsWidget.h index 86effb337..6be73375e 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.h +++ b/launcher/ui/widgets/MinecraftSettingsWidget.h @@ -56,6 +56,8 @@ class MinecraftSettingsWidget : public QWidget { void openGlobalSettings(); void updateAccountsMenu(const SettingsObject& settings); bool isQuickPlaySupported(); + private slots: + void selectedLoadersChanged(); MinecraftInstancePtr m_instance; Ui::MinecraftSettingsWidget* m_ui; diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.ui b/launcher/ui/widgets/MinecraftSettingsWidget.ui index ed12604fd..15406873a 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.ui +++ b/launcher/ui/widgets/MinecraftSettingsWidget.ui @@ -58,9 +58,9 @@ 0 - -207 - 603 - 694 + -537 + 623 + 1007 @@ -394,11 +394,67 @@ Qt::Horizontal + + + 0 + 0 + + + + + + Override Mod Download &Loaders + + + true + + + false + + + + + + NeoForge + + + + + + + Forge + + + + + + + Fabric + + + + + + + Quilt + + + + + + + LiteLoader + + + + + + @@ -433,8 +489,8 @@ 0 0 - 624 - 487 + 98 + 28 @@ -457,8 +513,8 @@ 0 0 - 624 - 487 + 299 + 499 diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index da41b990a..699f5f7d6 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -218,7 +218,14 @@ void ModFilterWidget::prepareBasicFilter() if (m_instance) { m_filter->hideInstalled = false; m_filter->side = ""; // or "both" - auto loaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); + ModPlatform::ModLoaderTypes loaders; + if (m_instance->settings()->get("OverrideModDownloadLoaders").toBool()) { + for (auto loader : m_instance->settings()->get("ModDownloadLoaders").toStringList()) { + loaders |= ModPlatform::getModLoaderFromString(loader); + } + } else { + loaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); + } ui->neoForge->setChecked(loaders & ModPlatform::NeoForge); ui->forge->setChecked(loaders & ModPlatform::Forge); ui->fabric->setChecked(loaders & ModPlatform::Fabric); From ca549714991be1888ed00a26dfdf19d49aede977 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 2 Jun 2025 09:29:37 +0300 Subject: [PATCH 62/62] chore: ensure the setting is saved as string Signed-off-by: Trial97 --- launcher/Json.cpp | 25 +++++++++++++++++++ launcher/Json.h | 6 ++++- launcher/minecraft/MinecraftInstance.cpp | 2 +- .../ui/widgets/MinecraftSettingsWidget.cpp | 5 ++-- launcher/ui/widgets/ModFilterWidget.cpp | 3 ++- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/launcher/Json.cpp b/launcher/Json.cpp index f397f89c5..8623eb2a8 100644 --- a/launcher/Json.cpp +++ b/launcher/Json.cpp @@ -279,4 +279,29 @@ QJsonValue requireIsType(const QJsonValue& value, const QString& wha return value; } +QStringList toStringList(const QString& jsonString) +{ + QJsonParseError parseError; + QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError); + + if (parseError.error != QJsonParseError::NoError || !doc.isArray()) + return {}; + try { + return ensureIsArrayOf(doc.array(), ""); + } catch (Json::JsonException& e) { + return {}; + } +} + +QString fromStringList(const QStringList& list) +{ + QJsonArray array; + for (const QString& str : list) { + array.append(str); + } + + QJsonDocument doc(toJsonArray(list)); + return QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); +} + } // namespace Json diff --git a/launcher/Json.h b/launcher/Json.h index c13be6470..509a41fd5 100644 --- a/launcher/Json.h +++ b/launcher/Json.h @@ -99,7 +99,7 @@ template QJsonArray toJsonArray(const QList& container) { QJsonArray array; - for (const T item : container) { + for (const T& item : container) { array.append(toJson(item)); } return array; @@ -278,5 +278,9 @@ JSON_HELPERFUNCTIONS(Variant, QVariant) #undef JSON_HELPERFUNCTIONS +// helper functions for settings +QStringList toStringList(const QString& jsonString); +QString fromStringList(const QStringList& list); + } // namespace Json using JSONValidationError = Json::JsonException; diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 90c066fe3..fafe7bd37 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -252,7 +252,7 @@ void MinecraftInstance::loadSpecificSettings() // Join server on launch, this does not have a global override m_settings->registerSetting("OverrideModDownloadLoaders", false); - m_settings->registerSetting("ModDownloadLoaders", QStringList()); + m_settings->registerSetting("ModDownloadLoaders", "[]"); qDebug() << "Instance-type specific settings were loaded!"; diff --git a/launcher/ui/widgets/MinecraftSettingsWidget.cpp b/launcher/ui/widgets/MinecraftSettingsWidget.cpp index 637e34db7..610dc143b 100644 --- a/launcher/ui/widgets/MinecraftSettingsWidget.cpp +++ b/launcher/ui/widgets/MinecraftSettingsWidget.cpp @@ -39,6 +39,7 @@ #include "Application.h" #include "BuildConfig.h" +#include "Json.h" #include "minecraft/PackProfile.h" #include "minecraft/WorldList.h" #include "minecraft/auth/AccountList.h" @@ -242,7 +243,7 @@ void MinecraftSettingsWidget::loadSettings() m_ui->liteLoader->blockSignals(true); auto instLoaders = m_instance->getPackProfile()->getSupportedModLoaders().value(); m_ui->loaderGroup->setChecked(settings->get("OverrideModDownloadLoaders").toBool()); - auto loaders = settings->get("ModDownloadLoaders").toStringList(); + auto loaders = Json::toStringList(settings->get("ModDownloadLoaders").toString()); if (loaders.isEmpty()) { m_ui->neoForge->setChecked(instLoaders & ModPlatform::NeoForge); m_ui->forge->setChecked(instLoaders & ModPlatform::Forge); @@ -499,5 +500,5 @@ void MinecraftSettingsWidget::selectedLoadersChanged() loaders << getModLoaderAsString(ModPlatform::Quilt); if (m_ui->liteLoader->isChecked()) loaders << getModLoaderAsString(ModPlatform::LiteLoader); - m_instance->settings()->set("ModDownloadLoaders", loaders); + m_instance->settings()->set("ModDownloadLoaders", Json::fromStringList(loaders)); } \ No newline at end of file diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 699f5f7d6..031ff0f94 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -40,6 +40,7 @@ #include #include #include "BaseVersionList.h" +#include "Json.h" #include "Version.h" #include "meta/Index.h" #include "modplatform/ModIndex.h" @@ -220,7 +221,7 @@ void ModFilterWidget::prepareBasicFilter() m_filter->side = ""; // or "both" ModPlatform::ModLoaderTypes loaders; if (m_instance->settings()->get("OverrideModDownloadLoaders").toBool()) { - for (auto loader : m_instance->settings()->get("ModDownloadLoaders").toStringList()) { + for (auto loader : Json::toStringList(m_instance->settings()->get("ModDownloadLoaders").toString())) { loaders |= ModPlatform::getModLoaderFromString(loader); } } else {