summaryrefslogtreecommitdiff
path: root/meshmc/launcher/ui/InstanceWindow.cpp
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:45:07 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:45:07 +0300
commit31b9a8949ed0a288143e23bf739f2eb64fdc63be (patch)
tree8a984fa143c38fccad461a77792d6864f3e82cd3 /meshmc/launcher/ui/InstanceWindow.cpp
parent934382c8a1ce738589dee9ee0f14e1cec812770e (diff)
parentfad6a1066616b69d7f5fef01178efdf014c59537 (diff)
downloadProject-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.tar.gz
Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.zip
Add 'meshmc/' from commit 'fad6a1066616b69d7f5fef01178efdf014c59537'
git-subtree-dir: meshmc git-subtree-mainline: 934382c8a1ce738589dee9ee0f14e1cec812770e git-subtree-split: fad6a1066616b69d7f5fef01178efdf014c59537
Diffstat (limited to 'meshmc/launcher/ui/InstanceWindow.cpp')
-rw-r--r--meshmc/launcher/ui/InstanceWindow.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/meshmc/launcher/ui/InstanceWindow.cpp b/meshmc/launcher/ui/InstanceWindow.cpp
new file mode 100644
index 0000000000..583530c0e4
--- /dev/null
+++ b/meshmc/launcher/ui/InstanceWindow.cpp
@@ -0,0 +1,258 @@
+/* SPDX-FileCopyrightText: 2026 Project Tick
+ * SPDX-FileContributor: Project Tick
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * MeshMC - A Custom Launcher for Minecraft
+ * Copyright (C) 2026 Project Tick
+ *
+ * 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * 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 "InstanceWindow.h"
+#include "Application.h"
+
+#include <QScrollBar>
+#include <QMessageBox>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <qlayoutitem.h>
+#include <QCloseEvent>
+
+#include "ui/dialogs/CustomMessageBox.h"
+#include "ui/dialogs/ProgressDialog.h"
+#include "ui/widgets/PageContainer.h"
+
+#include "InstancePageProvider.h"
+
+#include "icons/IconList.h"
+
+InstanceWindow::InstanceWindow(InstancePtr instance, QWidget* parent)
+ : QMainWindow(parent), m_instance(instance)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ auto icon = APPLICATION->icons()->getIcon(m_instance->iconKey());
+ QString windowTitle = tr("Console window for ") + m_instance->name();
+
+ // Set window properties
+ {
+ setWindowIcon(icon);
+ setWindowTitle(windowTitle);
+ }
+
+ // Add page container
+ {
+ auto provider = std::make_shared<InstancePageProvider>(m_instance);
+ m_container = new PageContainer(provider.get(), "console", this);
+ m_container->setParentContainer(this);
+ setCentralWidget(m_container);
+ setContentsMargins(0, 0, 0, 0);
+ }
+
+ // Add custom buttons to the page container layout.
+ {
+ auto horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setContentsMargins(6, -1, 6, -1);
+
+ auto btnHelp = new QPushButton();
+ btnHelp->setText(tr("Help"));
+ horizontalLayout->addWidget(btnHelp);
+ connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help()));
+
+ auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding,
+ QSizePolicy::Minimum);
+ horizontalLayout->addSpacerItem(spacer);
+
+ m_killButton = new QPushButton();
+ horizontalLayout->addWidget(m_killButton);
+ connect(m_killButton, SIGNAL(clicked(bool)),
+ SLOT(on_btnKillMinecraft_clicked()));
+
+ m_launchOfflineButton = new QPushButton();
+ horizontalLayout->addWidget(m_launchOfflineButton);
+ m_launchOfflineButton->setText(tr("Launch Offline"));
+ updateLaunchButtons();
+ connect(m_launchOfflineButton, SIGNAL(clicked(bool)),
+ SLOT(on_btnLaunchMinecraftOffline_clicked()));
+
+ m_closeButton = new QPushButton();
+ m_closeButton->setText(tr("Close"));
+ horizontalLayout->addWidget(m_closeButton);
+ connect(m_closeButton, SIGNAL(clicked(bool)),
+ SLOT(on_closeButton_clicked()));
+
+ m_container->addButtons(horizontalLayout);
+ }
+
+ // restore window state
+ {
+ auto base64State =
+ APPLICATION->settings()->get("ConsoleWindowState").toByteArray();
+ restoreState(QByteArray::fromBase64(base64State));
+ auto base64Geometry =
+ APPLICATION->settings()->get("ConsoleWindowGeometry").toByteArray();
+ restoreGeometry(QByteArray::fromBase64(base64Geometry));
+ }
+
+ // set up instance and launch process recognition
+ {
+ auto launchTask = m_instance->getLaunchTask();
+ on_InstanceLaunchTask_changed(launchTask);
+ connect(m_instance.get(), &BaseInstance::launchTaskChanged, this,
+ &InstanceWindow::on_InstanceLaunchTask_changed);
+ connect(m_instance.get(), &BaseInstance::runningStatusChanged, this,
+ &InstanceWindow::on_RunningState_changed);
+ }
+
+ // set up instance destruction detection
+ {
+ connect(m_instance.get(), &BaseInstance::statusChanged, this,
+ &InstanceWindow::on_instanceStatusChanged);
+ }
+ show();
+}
+
+void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status,
+ BaseInstance::Status newStatus)
+{
+ if (newStatus == BaseInstance::Status::Gone) {
+ m_doNotSave = true;
+ close();
+ }
+}
+
+void InstanceWindow::updateLaunchButtons()
+{
+ if (m_instance->isRunning()) {
+ m_launchOfflineButton->setEnabled(false);
+ m_killButton->setText(tr("Kill"));
+ m_killButton->setObjectName("killButton");
+ m_killButton->setToolTip(tr("Kill the running instance"));
+ } else if (!m_instance->canLaunch()) {
+ m_launchOfflineButton->setEnabled(false);
+ m_killButton->setText(tr("Launch"));
+ m_killButton->setObjectName("launchButton");
+ m_killButton->setToolTip(tr("Launch the instance"));
+ m_killButton->setEnabled(false);
+ } else {
+ m_launchOfflineButton->setEnabled(true);
+ m_killButton->setText(tr("Launch"));
+ m_killButton->setObjectName("launchButton");
+ m_killButton->setToolTip(tr("Launch the instance"));
+ }
+ // NOTE: this is a hack to force the button to recalculate its style
+ m_killButton->setStyleSheet("/* */");
+ m_killButton->setStyleSheet(QString());
+}
+
+void InstanceWindow::on_btnLaunchMinecraftOffline_clicked()
+{
+ APPLICATION->launch(m_instance, false, nullptr);
+}
+
+void InstanceWindow::on_InstanceLaunchTask_changed(
+ shared_qobject_ptr<LaunchTask> proc)
+{
+ m_proc = proc;
+}
+
+void InstanceWindow::on_RunningState_changed(bool running)
+{
+ updateLaunchButtons();
+ m_container->refreshContainer();
+ if (running) {
+ selectPage("log");
+ }
+}
+
+void InstanceWindow::on_closeButton_clicked()
+{
+ close();
+}
+
+void InstanceWindow::closeEvent(QCloseEvent* event)
+{
+ bool proceed = true;
+ if (!m_doNotSave) {
+ proceed &= m_container->prepareToClose();
+ }
+
+ if (!proceed) {
+ return;
+ }
+
+ APPLICATION->settings()->set("ConsoleWindowState", saveState().toBase64());
+ APPLICATION->settings()->set("ConsoleWindowGeometry",
+ saveGeometry().toBase64());
+ emit isClosing();
+ event->accept();
+}
+
+bool InstanceWindow::saveAll()
+{
+ return m_container->saveAll();
+}
+
+void InstanceWindow::on_btnKillMinecraft_clicked()
+{
+ if (m_instance->isRunning()) {
+ APPLICATION->kill(m_instance);
+ } else {
+ APPLICATION->launch(m_instance, true, nullptr);
+ }
+}
+
+QString InstanceWindow::instanceId()
+{
+ return m_instance->id();
+}
+
+bool InstanceWindow::selectPage(QString pageId)
+{
+ return m_container->selectPage(pageId);
+}
+
+void InstanceWindow::refreshContainer()
+{
+ m_container->refreshContainer();
+}
+
+InstanceWindow::~InstanceWindow() {}
+
+bool InstanceWindow::requestClose()
+{
+ if (m_container->prepareToClose()) {
+ close();
+ return true;
+ }
+ return false;
+}