diff options
-rw-r--r-- | launcher/CMakeLists.txt | 1 | ||||
-rw-r--r-- | launcher/ui/MainWindow.cpp | 929 | ||||
-rw-r--r-- | launcher/ui/MainWindow.h | 24 | ||||
-rw-r--r-- | launcher/ui/MainWindow.ui | 697 | ||||
-rw-r--r-- | launcher/ui/widgets/WideBar.cpp | 7 |
5 files changed, 844 insertions, 814 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 65f58667..093f44d3 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -942,6 +942,7 @@ SET(LAUNCHER_SOURCES ) qt_wrap_ui(LAUNCHER_UI + ui/MainWindow.ui ui/setupwizard/PasteWizardPage.ui ui/setupwizard/ThemeWizardPage.ui ui/pages/global/AccountListPage.ui diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 655e7df0..30bbf685 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,6 +43,7 @@ #include "FileSystem.h" #include "MainWindow.h" +#include "ui_MainWindow.h" #include <QVariant> #include <QUrl> @@ -139,785 +140,96 @@ QString profileInUseFilter(const QString & profile, bool used) } } -// WHY: to hold the pre-translation strings together with the T pointer, so it can be retranslated without a lot of ugly code -template <typename T> -class Translated +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { -public: - Translated(){} - Translated(QWidget *parent) - { - m_contained = new T(parent); - } - void setTooltipId(const char * tooltip) - { - m_tooltip = tooltip; - } - void setTextId(const char * text) - { - m_text = text; - } - operator T*() - { - return m_contained; - } - T * operator->() - { - return m_contained; - } - void retranslate() - { - if(m_text) - { - QString result; - result = QApplication::translate("MainWindow", m_text); - if(result.contains("%1")) { - result = result.arg(BuildConfig.LAUNCHER_DISPLAYNAME); - } - m_contained->setText(result); - } - if(m_tooltip) - { - QString result; - result = QApplication::translate("MainWindow", m_tooltip); - if(result.contains("%1")) { - result = result.arg(BuildConfig.LAUNCHER_DISPLAYNAME); - } - m_contained->setToolTip(result); - } - } -private: - T * m_contained = nullptr; - const char * m_text = nullptr; - const char * m_tooltip = nullptr; -}; -using TranslatedAction = Translated<QAction>; -using TranslatedToolButton = Translated<QToolButton>; - -class TranslatedToolbar -{ -public: - TranslatedToolbar(){} - TranslatedToolbar(QWidget *parent) - { - m_contained = new QToolBar(parent); - } - void setWindowTitleId(const char * title) - { - m_title = title; - } - operator QToolBar*() - { - return m_contained; - } - QToolBar * operator->() - { - return m_contained; - } - void retranslate() - { - if(m_title) - { - m_contained->setWindowTitle(QApplication::translate("MainWindow", m_title)); - } - } -private: - QToolBar * m_contained = nullptr; - const char * m_title = nullptr; -}; - -class MainWindow::Ui -{ -public: - TranslatedAction actionAddInstance; - //TranslatedAction actionRefresh; - TranslatedAction actionCheckUpdate; - TranslatedAction actionSettings; - TranslatedAction actionMoreNews; - TranslatedAction actionManageAccounts; - TranslatedAction actionLaunchInstance; - TranslatedAction actionKillInstance; - TranslatedAction actionRenameInstance; - TranslatedAction actionChangeInstGroup; - TranslatedAction actionChangeInstIcon; - TranslatedAction actionEditInstance; - TranslatedAction actionViewSelectedInstFolder; - TranslatedAction actionDeleteInstance; - TranslatedAction actionCAT; - TranslatedAction actionCopyInstance; - TranslatedAction actionLaunchInstanceOffline; - TranslatedAction actionLaunchInstanceDemo; - TranslatedAction actionExportInstance; - TranslatedAction actionCreateInstanceShortcut; - QVector<TranslatedAction *> all_actions; - - LabeledToolButton *renameButton = nullptr; - LabeledToolButton *changeIconButton = nullptr; - - QMenu * foldersMenu = nullptr; - TranslatedToolButton foldersMenuButton; - TranslatedAction actionViewInstanceFolder; - TranslatedAction actionViewCentralModsFolder; - - QMenu * editMenu = nullptr; - TranslatedAction actionUndoTrashInstance; - - QMenu * helpMenu = nullptr; - TranslatedToolButton helpMenuButton; - TranslatedAction actionClearMetadata; - #ifdef Q_OS_MAC - TranslatedAction actionAddToPATH; - #endif - TranslatedAction actionReportBug; - TranslatedAction actionDISCORD; - TranslatedAction actionMATRIX; - TranslatedAction actionREDDIT; - TranslatedAction actionAbout; - - TranslatedAction actionNoAccountsAdded; - TranslatedAction actionNoDefaultAccount; - - TranslatedAction actionLockToolbars; - - TranslatedAction actionChangeTheme; - - QVector<TranslatedToolButton *> all_toolbuttons; - - QWidget *centralWidget = nullptr; - QHBoxLayout *horizontalLayout = nullptr; - QStatusBar *statusBar = nullptr; - - QMenuBar *menuBar = nullptr; - QMenu *fileMenu; - QMenu *viewMenu; - QMenu *profileMenu; - - TranslatedAction actionCloseWindow; - - TranslatedAction actionOpenWiki; - TranslatedAction actionNewsMenuBar; - - TranslatedToolbar mainToolBar; - TranslatedToolbar instanceToolBar; - TranslatedToolbar newsToolBar; - QVector<TranslatedToolbar *> all_toolbars; - - void createMainToolbarActions(MainWindow *MainWindow) - { - actionAddInstance = TranslatedAction(MainWindow); - actionAddInstance->setObjectName(QStringLiteral("actionAddInstance")); - actionAddInstance->setIcon(APPLICATION->getThemedIcon("new")); - actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instanc&e...")); - actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance.")); - actionAddInstance->setShortcut(QKeySequence::New); - all_actions.append(&actionAddInstance); - - actionViewInstanceFolder = TranslatedAction(MainWindow); - actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder")); - actionViewInstanceFolder->setIcon(APPLICATION->getThemedIcon("viewfolder")); - actionViewInstanceFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&View Instance Folder")); - actionViewInstanceFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance folder in a file browser.")); - all_actions.append(&actionViewInstanceFolder); - - actionViewCentralModsFolder = TranslatedAction(MainWindow); - actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); - actionViewCentralModsFolder->setIcon(APPLICATION->getThemedIcon("centralmods")); - actionViewCentralModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View &Central Mods Folder")); - actionViewCentralModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the central mods folder in a file browser.")); - all_actions.append(&actionViewCentralModsFolder); - - foldersMenu = new QMenu(MainWindow); - foldersMenu->setTitle(tr("F&olders")); - foldersMenu->setToolTipsVisible(true); - - foldersMenu->addAction(actionViewInstanceFolder); - foldersMenu->addAction(actionViewCentralModsFolder); - - foldersMenuButton = TranslatedToolButton(MainWindow); - foldersMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "F&olders")); - foldersMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open one of the folders shared between instances.")); - foldersMenuButton->setMenu(foldersMenu); - foldersMenuButton->setPopupMode(QToolButton::InstantPopup); - foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - foldersMenuButton->setIcon(APPLICATION->getThemedIcon("viewfolder")); - foldersMenuButton->setFocusPolicy(Qt::NoFocus); - all_toolbuttons.append(&foldersMenuButton); - - actionSettings = TranslatedAction(MainWindow); - actionSettings->setObjectName(QStringLiteral("actionSettings")); - actionSettings->setIcon(APPLICATION->getThemedIcon("settings")); - actionSettings->setMenuRole(QAction::PreferencesRole); - actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Setti&ngs...")); - actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings.")); - actionSettings->setShortcut(QKeySequence::Preferences); - all_actions.append(&actionSettings); - - actionUndoTrashInstance = TranslatedAction(MainWindow); - actionUndoTrashInstance->setObjectName(QStringLiteral("actionUndoTrashInstance")); - actionUndoTrashInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Undo Last Instance Deletion")); - actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); - actionUndoTrashInstance->setShortcut(QKeySequence::Undo); - all_actions.append(&actionUndoTrashInstance); - - actionClearMetadata = TranslatedAction(MainWindow); - actionClearMetadata->setObjectName(QStringLiteral("actionClearMetadata")); - actionClearMetadata->setIcon(APPLICATION->getThemedIcon("refresh")); - actionClearMetadata.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Clear Metadata Cache")); - actionClearMetadata.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Clear cached metadata")); - all_actions.append(&actionClearMetadata); - - #ifdef Q_OS_MAC - actionAddToPATH = TranslatedAction(MainWindow); - actionAddToPATH->setObjectName(QStringLiteral("actionAddToPATH")); - actionAddToPATH.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Install to &PATH")); - actionAddToPATH.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Install a prismlauncher symlink to /usr/local/bin")); - all_actions.append(&actionAddToPATH); - #endif - - if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { - actionReportBug = TranslatedAction(MainWindow); - actionReportBug->setObjectName(QStringLiteral("actionReportBug")); - actionReportBug->setIcon(APPLICATION->getThemedIcon("bug")); - actionReportBug.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Report a &Bug...")); - actionReportBug.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the bug tracker to report a bug with %1.")); - all_actions.append(&actionReportBug); - } - - if(!BuildConfig.MATRIX_URL.isEmpty()) { - actionMATRIX = TranslatedAction(MainWindow); - actionMATRIX->setObjectName(QStringLiteral("actionMATRIX")); - actionMATRIX->setIcon(APPLICATION->getThemedIcon("matrix")); - actionMATRIX.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Matrix Space")); - actionMATRIX.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 Matrix space")); - all_actions.append(&actionMATRIX); - } - - if (!BuildConfig.DISCORD_URL.isEmpty()) { - actionDISCORD = TranslatedAction(MainWindow); - actionDISCORD->setObjectName(QStringLiteral("actionDISCORD")); - actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord")); - actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Discord Guild")); - actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 Discord guild.")); - all_actions.append(&actionDISCORD); - } - - if (!BuildConfig.SUBREDDIT_URL.isEmpty()) { - actionREDDIT = TranslatedAction(MainWindow); - actionREDDIT->setObjectName(QStringLiteral("actionREDDIT")); - actionREDDIT->setIcon(APPLICATION->getThemedIcon("reddit-alien")); - actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Sub&reddit")); - actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 subreddit.")); - all_actions.append(&actionREDDIT); - } - - actionAbout = TranslatedAction(MainWindow); - actionAbout->setObjectName(QStringLiteral("actionAbout")); - actionAbout->setIcon(APPLICATION->getThemedIcon("about")); - actionAbout->setMenuRole(QAction::AboutRole); - actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&About %1")); - actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about %1.")); - all_actions.append(&actionAbout); - - if(BuildConfig.UPDATER_ENABLED) - { - actionCheckUpdate = TranslatedAction(MainWindow); - actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); - actionCheckUpdate->setIcon(APPLICATION->getThemedIcon("checkupdate")); - actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Update...")); - actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for %1.")); - actionCheckUpdate->setMenuRole(QAction::ApplicationSpecificRole); - all_actions.append(&actionCheckUpdate); - } - - actionCAT = TranslatedAction(MainWindow); - actionCAT->setObjectName(QStringLiteral("actionCAT")); - actionCAT->setCheckable(true); - actionCAT->setIcon(APPLICATION->getThemedIcon("cat")); - actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Meow")); - actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3")); - actionCAT->setPriority(QAction::LowPriority); - all_actions.append(&actionCAT); - - // profile menu and its actions - actionManageAccounts = TranslatedAction(MainWindow); - actionManageAccounts->setObjectName(QStringLiteral("actionManageAccounts")); - actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Manage Accounts...")); - // FIXME: no tooltip! - actionManageAccounts->setCheckable(false); - actionManageAccounts->setIcon(APPLICATION->getThemedIcon("accounts")); - all_actions.append(&actionManageAccounts); - - actionLockToolbars = TranslatedAction(MainWindow); - actionLockToolbars->setObjectName(QStringLiteral("actionLockToolbars")); - actionLockToolbars.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Lock Toolbars")); - actionLockToolbars->setCheckable(true); - all_actions.append(&actionLockToolbars); - - actionChangeTheme = TranslatedAction(MainWindow); - actionChangeTheme->setObjectName(QStringLiteral("actionChangeTheme")); - actionChangeTheme.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Themes")); - all_actions.append(&actionChangeTheme); - } + ui->setupUi(this); - void createMainToolbar(QMainWindow *MainWindow) + // instance toolbar stuff { - mainToolBar = TranslatedToolbar(MainWindow); - mainToolBar->setVisible(menuBar->isNativeMenuBar() || !APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool()); - mainToolBar->setObjectName(QStringLiteral("mainToolBar")); - mainToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); - mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - mainToolBar->setFloatable(false); - mainToolBar.setWindowTitleId(QT_TRANSLATE_NOOP("MainWindow", "Main Toolbar")); - - mainToolBar->addAction(actionAddInstance); - - mainToolBar->addSeparator(); - - QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow); - foldersButtonAction->setDefaultWidget(foldersMenuButton); - mainToolBar->addAction(foldersButtonAction); - - mainToolBar->addAction(actionSettings); - - helpMenu = new QMenu(MainWindow); - helpMenu->setToolTipsVisible(true); - - helpMenu->addAction(actionClearMetadata); - - #ifdef Q_OS_MAC - helpMenu->addAction(actionAddToPATH); - #endif - - if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { - helpMenu->addAction(actionReportBug); - } - - if(!BuildConfig.MATRIX_URL.isEmpty()) { - helpMenu->addAction(actionMATRIX); - } - - if (!BuildConfig.DISCORD_URL.isEmpty()) { - helpMenu->addAction(actionDISCORD); - } - - if (!BuildConfig.SUBREDDIT_URL.isEmpty()) { - helpMenu->addAction(actionREDDIT); - } - - helpMenu->addAction(actionAbout); - - helpMenuButton = TranslatedToolButton(MainWindow); - helpMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Help")); - helpMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Get help with %1 or Minecraft.")); - helpMenuButton->setMenu(helpMenu); - helpMenuButton->setPopupMode(QToolButton::InstantPopup); - helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - helpMenuButton->setIcon(APPLICATION->getThemedIcon("help")); - helpMenuButton->setFocusPolicy(Qt::NoFocus); - all_toolbuttons.append(&helpMenuButton); - QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow); - helpButtonAction->setDefaultWidget(helpMenuButton); - mainToolBar->addAction(helpButtonAction); - - if(BuildConfig.UPDATER_ENABLED) - { - mainToolBar->addAction(actionCheckUpdate); - } + // Qt doesn't like vertical moving toolbars, so we have to force them... + // See https://github.com/PolyMC/PolyMC/issues/493 + connect(ui->instanceToolBar, &QToolBar::orientationChanged, + [=](Qt::Orientation) { ui->instanceToolBar->setOrientation(Qt::Vertical); }); - mainToolBar->addSeparator(); - - mainToolBar->addAction(actionCAT); - - all_toolbars.append(&mainToolBar); - MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar); - } - - void createMenuBar(QMainWindow *MainWindow) - { - menuBar = new QMenuBar(MainWindow); - menuBar->setVisible(APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool()); - - fileMenu = menuBar->addMenu(tr("&File")); - // Workaround for QTBUG-94802 (https://bugreports.qt.io/browse/QTBUG-94802); also present for other menus - fileMenu->setSeparatorsCollapsible(false); - fileMenu->addAction(actionAddInstance); - fileMenu->addAction(actionLaunchInstance); - fileMenu->addAction(actionKillInstance); - fileMenu->addAction(actionCloseWindow); - fileMenu->addSeparator(); - fileMenu->addAction(actionEditInstance); - fileMenu->addAction(actionChangeInstGroup); - fileMenu->addAction(actionViewSelectedInstFolder); - fileMenu->addAction(actionExportInstance); - fileMenu->addAction(actionCopyInstance); - fileMenu->addAction(actionDeleteInstance); - fileMenu->addAction(actionCreateInstanceShortcut); - fileMenu->addSeparator(); - fileMenu->addAction(actionSettings); - - editMenu = menuBar->addMenu(tr("&Edit")); - editMenu->addAction(actionUndoTrashInstance); - - viewMenu = menuBar->addMenu(tr("&View")); - viewMenu->setSeparatorsCollapsible(false); - viewMenu->addAction(actionChangeTheme); - viewMenu->addSeparator(); - viewMenu->addAction(actionCAT); - viewMenu->addSeparator(); - - viewMenu->addAction(actionLockToolbars); - - menuBar->addMenu(foldersMenu); - - profileMenu = menuBar->addMenu(tr("&Accounts")); - profileMenu->setSeparatorsCollapsible(false); - profileMenu->addAction(actionManageAccounts); - - helpMenu = menuBar->addMenu(tr("&Help")); - helpMenu->setSeparatorsCollapsible(false); - helpMenu->addAction(actionClearMetadata); - #ifdef Q_OS_MAC - helpMenu->addAction(actionAddToPATH); - #endif - helpMenu->addSeparator(); - helpMenu->addAction(actionAbout); - helpMenu->addAction(actionOpenWiki); - helpMenu->addAction(actionNewsMenuBar); - helpMenu->addSeparator(); - if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) - helpMenu->addAction(actionReportBug); - if (!BuildConfig.MATRIX_URL.isEmpty()) - helpMenu->addAction(actionMATRIX); - if (!BuildConfig.DISCORD_URL.isEmpty()) - helpMenu->addAction(actionDISCORD); - if (!BuildConfig.SUBREDDIT_URL.isEmpty()) - helpMenu->addAction(actionREDDIT); - if(BuildConfig.UPDATER_ENABLED) - { - helpMenu->addSeparator(); - helpMenu->addAction(actionCheckUpdate); - } - MainWindow->setMenuBar(menuBar); - } - - void createMenuActions(MainWindow *MainWindow) - { - actionCloseWindow = TranslatedAction(MainWindow); - actionCloseWindow->setObjectName(QStringLiteral("actionCloseWindow")); - actionCloseWindow.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Close &Window")); - actionCloseWindow.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Close the current window")); - actionCloseWindow->setShortcut(QKeySequence::Close); - connect(actionCloseWindow, &QAction::triggered, APPLICATION, &Application::closeCurrentWindow); - all_actions.append(&actionCloseWindow); - - actionOpenWiki = TranslatedAction(MainWindow); - actionOpenWiki->setObjectName(QStringLiteral("actionOpenWiki")); - actionOpenWiki.setTextId(QT_TRANSLATE_NOOP("MainWindow", "%1 &Help")); - actionOpenWiki.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 wiki")); - actionOpenWiki->setIcon(APPLICATION->getThemedIcon("help")); - connect(actionOpenWiki, &QAction::triggered, MainWindow, &MainWindow::on_actionOpenWiki_triggered); - all_actions.append(&actionOpenWiki); - - actionNewsMenuBar = TranslatedAction(MainWindow); - actionNewsMenuBar->setObjectName(QStringLiteral("actionNewsMenuBar")); - actionNewsMenuBar.setTextId(QT_TRANSLATE_NOOP("MainWindow", "%1 &News")); - actionNewsMenuBar.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 wiki")); - actionNewsMenuBar->setIcon(APPLICATION->getThemedIcon("news")); - connect(actionNewsMenuBar, &QAction::triggered, MainWindow, &MainWindow::on_actionMoreNews_triggered); - all_actions.append(&actionNewsMenuBar); - } - - // "Instance actions" are actions that require an instance to be selected (i.e. "new instance" is not here) - // Actions that also require other conditions (e.g. a running instance) won't be changed. - void setInstanceActionsEnabled(bool enabled) - { - actionEditInstance->setEnabled(enabled); - actionChangeInstGroup->setEnabled(enabled); - actionViewSelectedInstFolder->setEnabled(enabled); - actionExportInstance->setEnabled(enabled); - actionDeleteInstance->setEnabled(enabled); - actionCopyInstance->setEnabled(enabled); - actionCreateInstanceShortcut->setEnabled(enabled); - } - - void createStatusBar(QMainWindow *MainWindow) - { - statusBar = new QStatusBar(MainWindow); - statusBar->setObjectName(QStringLiteral("statusBar")); - MainWindow->setStatusBar(statusBar); - } - - void createNewsToolbar(QMainWindow *MainWindow) - { - newsToolBar = TranslatedToolbar(MainWindow); - newsToolBar->setObjectName(QStringLiteral("newsToolBar")); - newsToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); - newsToolBar->setIconSize(QSize(16, 16)); - newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - newsToolBar->setFloatable(false); - newsToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "News Toolbar")); - - actionMoreNews = TranslatedAction(MainWindow); - actionMoreNews->setObjectName(QStringLiteral("actionMoreNews")); - actionMoreNews->setIcon(APPLICATION->getThemedIcon("news")); - actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news...")); - actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the development blog to read more news about %1.")); - all_actions.append(&actionMoreNews); - newsToolBar->addAction(actionMoreNews); - - all_toolbars.append(&newsToolBar); - MainWindow->addToolBar(Qt::BottomToolBarArea, newsToolBar); - } - - void createInstanceActions(QMainWindow *MainWindow) - { - // NOTE: not added to toolbar, but used for instance context menu (right click) - actionChangeInstIcon = TranslatedAction(MainWindow); - actionChangeInstIcon->setObjectName(QStringLiteral("actionChangeInstIcon")); - actionChangeInstIcon->setIcon(QIcon(":/icons/instances/grass")); - actionChangeInstIcon->setIconVisibleInMenu(true); - actionChangeInstIcon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Change Icon")); - actionChangeInstIcon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's icon.")); - all_actions.append(&actionChangeInstIcon); - - changeIconButton = new LabeledToolButton(MainWindow); + // if you try to add a widget to a toolbar in a .ui file + // qt designer will delete it when you save the file >:( + changeIconButton = new LabeledToolButton(this); changeIconButton->setObjectName(QStringLiteral("changeIconButton")); changeIconButton->setIcon(APPLICATION->getThemedIcon("news")); - changeIconButton->setToolTip(actionChangeInstIcon->toolTip()); changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + connect(changeIconButton, &QToolButton::clicked, this, &MainWindow::on_actionChangeInstIcon_triggered); + ui->instanceToolBar->insertWidgetBefore(ui->actionLaunchInstance, changeIconButton); - // NOTE: not added to toolbar, but used for instance context menu (right click) - actionRenameInstance = TranslatedAction(MainWindow); - actionRenameInstance->setObjectName(QStringLiteral("actionRenameInstance")); - actionRenameInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Rename")); - actionRenameInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Rename the selected instance.")); - actionRenameInstance->setIcon(APPLICATION->getThemedIcon("rename")); - all_actions.append(&actionRenameInstance); - - // the rename label is inside the rename tool button - renameButton = new LabeledToolButton(MainWindow); + renameButton = new LabeledToolButton(this); renameButton->setObjectName(QStringLiteral("renameButton")); - renameButton->setToolTip(actionRenameInstance->toolTip()); renameButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + connect(renameButton, &QToolButton::clicked, this, &MainWindow::on_actionRenameInstance_triggered); + ui->instanceToolBar->insertWidgetBefore(ui->actionLaunchInstance, renameButton); - actionLaunchInstance = TranslatedAction(MainWindow); - actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance")); - actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Launch")); - actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance.")); - actionLaunchInstance->setIcon(APPLICATION->getThemedIcon("launch")); - all_actions.append(&actionLaunchInstance); - - actionLaunchInstanceOffline = TranslatedAction(MainWindow); - actionLaunchInstanceOffline->setObjectName(QStringLiteral("actionLaunchInstanceOffline")); - actionLaunchInstanceOffline.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch &Offline")); - actionLaunchInstanceOffline.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance in offline mode.")); - all_actions.append(&actionLaunchInstanceOffline); - - actionLaunchInstanceDemo = TranslatedAction(MainWindow); - actionLaunchInstanceDemo->setObjectName(QStringLiteral("actionLaunchInstanceDemo")); - actionLaunchInstanceDemo.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch &Demo")); - actionLaunchInstanceDemo.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance in demo mode.")); - all_actions.append(&actionLaunchInstanceDemo); - - actionKillInstance = TranslatedAction(MainWindow); - actionKillInstance->setObjectName(QStringLiteral("actionKillInstance")); - actionKillInstance->setDisabled(true); - actionKillInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Kill")); - actionKillInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Kill the running instance")); - actionKillInstance->setShortcut(QKeySequence(tr("Ctrl+K"))); - actionKillInstance->setIcon(APPLICATION->getThemedIcon("status-bad")); - all_actions.append(&actionKillInstance); - - actionEditInstance = TranslatedAction(MainWindow); - actionEditInstance->setObjectName(QStringLiteral("actionEditInstance")); - actionEditInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Edit...")); - actionEditInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the instance settings, mods and versions.")); - actionEditInstance->setShortcut(QKeySequence(tr("Ctrl+I"))); - actionEditInstance->setIcon(APPLICATION->getThemedIcon("settings-configure")); - all_actions.append(&actionEditInstance); - - actionChangeInstGroup = TranslatedAction(MainWindow); - actionChangeInstGroup->setObjectName(QStringLiteral("actionChangeInstGroup")); - actionChangeInstGroup.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Change Group...")); - actionChangeInstGroup.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's group.")); - actionChangeInstGroup->setShortcut(QKeySequence(tr("Ctrl+G"))); - actionChangeInstGroup->setIcon(APPLICATION->getThemedIcon("tag")); - all_actions.append(&actionChangeInstGroup); - - actionViewSelectedInstFolder = TranslatedAction(MainWindow); - actionViewSelectedInstFolder->setObjectName(QStringLiteral("actionViewSelectedInstFolder")); - actionViewSelectedInstFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Folder")); - actionViewSelectedInstFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the selected instance's root folder in a file browser.")); - actionViewSelectedInstFolder->setIcon(APPLICATION->getThemedIcon("viewfolder")); - all_actions.append(&actionViewSelectedInstFolder); - - actionExportInstance = TranslatedAction(MainWindow); - actionExportInstance->setObjectName(QStringLiteral("actionExportInstance")); - actionExportInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "E&xport...")); - actionExportInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Export the selected instance as a zip file.")); - actionExportInstance->setShortcut(QKeySequence(tr("Ctrl+E"))); - actionExportInstance->setIcon(APPLICATION->getThemedIcon("export")); - all_actions.append(&actionExportInstance); - - actionDeleteInstance = TranslatedAction(MainWindow); - actionDeleteInstance->setObjectName(QStringLiteral("actionDeleteInstance")); - actionDeleteInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Dele&te")); - actionDeleteInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Delete the selected instance.")); - actionDeleteInstance->setShortcuts({QKeySequence(tr("Backspace")), QKeySequence::Delete}); - actionDeleteInstance->setAutoRepeat(false); - actionDeleteInstance->setIcon(APPLICATION->getThemedIcon("delete")); - all_actions.append(&actionDeleteInstance); - - actionCopyInstance = TranslatedAction(MainWindow); - actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance")); - actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Cop&y...")); - actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance.")); - actionCopyInstance->setShortcut(QKeySequence(tr("Ctrl+D"))); - actionCopyInstance->setIcon(APPLICATION->getThemedIcon("copy")); - all_actions.append(&actionCopyInstance); - - actionCreateInstanceShortcut = TranslatedAction(MainWindow); - actionCreateInstanceShortcut->setObjectName(QStringLiteral("actionCreateInstanceShortcut")); - actionCreateInstanceShortcut.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Create Shortcut")); - actionCreateInstanceShortcut.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Creates a shortcut on your desktop to launch the selected instance.")); - actionCreateInstanceShortcut->setIcon(APPLICATION->getThemedIcon("shortcut")); - all_actions.append(&actionCreateInstanceShortcut); + // restore the instance toolbar settings + auto const setting_name = QString("WideBarVisibility_%1").arg(ui->instanceToolBar->objectName()); + if (!APPLICATION->settings()->contains(setting_name)) + instanceToolbarSetting = APPLICATION->settings()->registerSetting(setting_name); + else + instanceToolbarSetting = APPLICATION->settings()->getSetting(setting_name); - setInstanceActionsEnabled(false); + ui->instanceToolBar->setVisibilityState(instanceToolbarSetting->get().toByteArray()); } - void createInstanceToolbar(QMainWindow *MainWindow) + // set the menu for the folders and help tool buttons { - instanceToolBar = TranslatedToolbar(MainWindow); - instanceToolBar->setObjectName(QStringLiteral("instanceToolBar")); - // disabled until we have an instance selected - instanceToolBar->setEnabled(false); - // Qt doesn't like vertical moving toolbars, so we have to force them... - // See https://github.com/PolyMC/PolyMC/issues/493 - connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); - instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); - instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - instanceToolBar->setIconSize(QSize(16, 16)); - - instanceToolBar->setFloatable(false); - instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar")); - - instanceToolBar->addWidget(changeIconButton); - instanceToolBar->addWidget(renameButton); - - instanceToolBar->addSeparator(); - - instanceToolBar->addAction(actionLaunchInstance); - instanceToolBar->addAction(actionKillInstance); - - instanceToolBar->addSeparator(); - - instanceToolBar->addAction(actionEditInstance); - instanceToolBar->addAction(actionChangeInstGroup); - - instanceToolBar->addAction(actionViewSelectedInstFolder); - - instanceToolBar->addAction(actionExportInstance); - instanceToolBar->addAction(actionCopyInstance); - instanceToolBar->addAction(actionDeleteInstance); - - instanceToolBar->addAction(actionCreateInstanceShortcut); // TODO find better position for this - - QLayout * lay = instanceToolBar->layout(); - for(int i = 0; i < lay->count(); i++) - { - QLayoutItem * item = lay->itemAt(i); - if (item->widget()->metaObject()->className() == QString("QToolButton")) - { - item->setAlignment(Qt::AlignLeft); - } - } + auto foldersMenuButton = dynamic_cast<QToolButton*>(ui->mainToolBar->widgetForAction(ui->actionFoldersButton)); + foldersMenuButton->setMenu(ui->foldersMenu); + foldersMenuButton->setPopupMode(QToolButton::InstantPopup); - all_toolbars.append(&instanceToolBar); - MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar); + helpMenuButton = dynamic_cast<QToolButton*>(ui->mainToolBar->widgetForAction(ui->actionHelpButton)); + helpMenuButton->setMenu(ui->helpMenu); + helpMenuButton->setPopupMode(QToolButton::InstantPopup); } - void setupUi(MainWindow *MainWindow) + // hide, disable and show stuff { - if (MainWindow->objectName().isEmpty()) - { - MainWindow->setObjectName(QStringLiteral("MainWindow")); - } - MainWindow->resize(800, 600); - MainWindow->setWindowIcon(APPLICATION->getThemedIcon("logo")); - MainWindow->setWindowTitle(APPLICATION->applicationDisplayName()); -#ifndef QT_NO_ACCESSIBILITY - MainWindow->setAccessibleName(BuildConfig.LAUNCHER_DISPLAYNAME); -#endif - - createMainToolbarActions(MainWindow); - createMenuActions(MainWindow); - createInstanceActions(MainWindow); - - createMenuBar(MainWindow); - - createMainToolbar(MainWindow); - - centralWidget = new QWidget(MainWindow); - centralWidget->setObjectName(QStringLiteral("centralWidget")); - horizontalLayout = new QHBoxLayout(centralWidget); - horizontalLayout->setSpacing(0); - horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); - horizontalLayout->setSizeConstraint(QLayout::SetDefaultConstraint); - horizontalLayout->setContentsMargins(0, 0, 0, 0); - MainWindow->setCentralWidget(centralWidget); + ui->actionReportBug->setVisible(!BuildConfig.BUG_TRACKER_URL.isEmpty()); + ui->actionMATRIX->setVisible(!BuildConfig.MATRIX_URL.isEmpty()); + ui->actionDISCORD->setVisible(!BuildConfig.DISCORD_URL.isEmpty()); + ui->actionREDDIT->setVisible(!BuildConfig.SUBREDDIT_URL.isEmpty()); - createStatusBar(MainWindow); - createNewsToolbar(MainWindow); - createInstanceToolbar(MainWindow); + ui->actionCheckUpdate->setVisible(BuildConfig.UPDATER_ENABLED); - MainWindow->updateToolsMenu(); - MainWindow->updateThemeMenu(); - - retranslateUi(MainWindow); - - QMetaObject::connectSlotsByName(MainWindow); - } // setupUi - - void retranslateUi(MainWindow *MainWindow) - { - // all the actions - for(auto * item: all_actions) - { - item->retranslate(); - } - for(auto * item: all_toolbars) - { - item->retranslate(); - } - for(auto * item: all_toolbuttons) - { - item->retranslate(); - } - // submenu buttons - foldersMenuButton->setText(tr("Folders")); - helpMenuButton->setText(tr("Help")); + ui->actionAddToPATH->setVisible(false); +#ifdef Q_OS_MAC + ui->actionAddToPATH->setVisible(true); +#endif - // playtime counter - if (MainWindow->m_statusCenter) - { - MainWindow->updateStatusCenter(); - } - } // retranslateUi -}; + // disabled until we have an instance selected + ui->instanceToolBar->setEnabled(false); + ui->actionKillInstance->setEnabled(false); + ui->actionLaunchInstance->setEnabled(false); + setInstanceActionsEnabled(false); + } -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow::Ui) -{ - ui->setupUi(this); + // add the toolbar toggles to the view menu + ui->viewMenu->addAction(ui->instanceToolBar->toggleViewAction()); + ui->viewMenu->addAction(ui->newsToolBar->toggleViewAction()); + updateThemeMenu(); + updateMainToolBar(); // OSX magic. setUnifiedTitleAndToolBarOnMac(true); // Global shortcuts { + // you can't set QKeySequence::StandardKey shortcuts in qt designer >:( + ui->actionAddInstance->setShortcut(QKeySequence::New); + ui->actionSettings->setShortcut(QKeySequence::Preferences); + ui->actionUndoTrashInstance->setShortcut(QKeySequence::Undo); + ui->actionDeleteInstance->setShortcuts({ QKeySequence(tr("Backspace")), QKeySequence::Delete }); + ui->actionCloseWindow->setShortcut(QKeySequence::Close); + connect(ui->actionCloseWindow, &QAction::triggered, APPLICATION, &Application::closeCurrentWindow); + // FIXME: This is kinda weird. and bad. We need some kind of managed shutdown. auto q = new QShortcut(QKeySequence::Quit, this); - connect(q, SIGNAL(activated()), qApp, SLOT(quit())); + connect(q, &QShortcut::activated, APPLICATION, &Application::quit); } // Konami Code @@ -929,12 +241,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // Add the news label to the news toolbar. { m_newsChecker.reset(new NewsChecker(APPLICATION->network(), BuildConfig.NEWS_RSS_URL)); - newsLabel = new QToolButton(); - newsLabel->setIcon(APPLICATION->getThemedIcon("news")); - newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - newsLabel->setFocusPolicy(Qt::NoFocus); - ui->newsToolBar->insertWidget(ui->actionMoreNews, newsLabel); + newsLabel = dynamic_cast<QToolButton*>(ui->newsToolBar->widgetForAction(ui->actionNewsLabel)); + + //add a spacer before the more news button + QWidget *spacer = new QWidget(); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + ui->newsToolBar->insertWidget(ui->actionMoreNews, spacer); + QObject::connect(newsLabel, &QAbstractButton::clicked, this, &MainWindow::newsButtonClicked); QObject::connect(m_newsChecker.get(), &NewsChecker::newsLoaded, this, &MainWindow::updateNewsLabel); updateNewsLabel(); @@ -970,10 +283,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow } // The cat background { + // set the cat action priority here so you can still see the action in qt designer + ui->actionCAT->setPriority(QAction::LowPriority); bool cat_enable = APPLICATION->settings()->get("TheCat").toBool(); ui->actionCAT->setChecked(cat_enable); - // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... - connect(ui->actionCAT.operator->(), SIGNAL(toggled(bool)), SLOT(onCatToggled(bool))); + connect(ui->actionCAT, &QAction::toggled, this, &MainWindow::onCatToggled); connect(APPLICATION, &Application::currentCatChanged, this, &MainWindow::onCatChanged); setCatBackground(cat_enable); } @@ -1011,7 +325,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // Add "manage accounts" button, right align QWidget *spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - ui->mainToolBar->addWidget(spacer); + ui->mainToolBar->insertWidget(ui->actionAccountsButton, spacer); accountMenu = new QMenu(this); // Use undocumented property... https://stackoverflow.com/questions/7121718/create-a-scrollbar-in-a-submenu-qt @@ -1019,16 +333,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow repopulateAccountsMenu(); - accountMenuButton = new QToolButton(this); + accountMenuButton = dynamic_cast<QToolButton *>(ui->mainToolBar->widgetForAction(ui->actionAccountsButton)); accountMenuButton->setMenu(accountMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); - accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); - - QWidgetAction *accountMenuButtonAction = new QWidgetAction(this); - accountMenuButtonAction->setDefaultWidget(accountMenuButton); - - ui->mainToolBar->addAction(accountMenuButtonAction); // Update the menu when the active account changes. // Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit. @@ -1067,8 +374,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow bool updatesAllowed = APPLICATION->updatesAreAllowed(); updatesAllowedChanged(updatesAllowed); - // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... - connect(ui->actionCheckUpdate.operator->(), &QAction::triggered, this, &MainWindow::checkForUpdates); + connect(ui->actionCheckUpdate, &QAction::triggered, this, &MainWindow::checkForUpdates); // set up the updater object. auto updater = APPLICATION->updateChecker(); @@ -1089,7 +395,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow } } - connect(ui->actionUndoTrashInstance.operator->(), &QAction::triggered, this, &MainWindow::undoTrashInstance); + connect(ui->actionUndoTrashInstance, &QAction::triggered, this, &MainWindow::undoTrashInstance); setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); @@ -1130,6 +436,20 @@ void MainWindow::retranslateUi() } ui->retranslateUi(this); + + changeIconButton->setToolTip(ui->actionChangeInstIcon->toolTip()); + renameButton->setToolTip(ui->actionRenameInstance->toolTip()); + + // replace the %1 with the launcher display name in some actions + if (helpMenuButton->toolTip().contains("%1")) + helpMenuButton->setToolTip(helpMenuButton->toolTip().arg(BuildConfig.LAUNCHER_DISPLAYNAME)); + + for (auto action : ui->helpMenu->actions()) { + if (action->text().contains("%1")) + action->setText(action->text().arg(BuildConfig.LAUNCHER_DISPLAYNAME)); + if (action->toolTip().contains("%1")) + action->setToolTip(action->toolTip().arg(BuildConfig.LAUNCHER_DISPLAYNAME)); + } } MainWindow::~MainWindow() @@ -1169,13 +489,16 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos) bool onInstance = view->indexAt(pos).isValid(); if (onInstance) { - actions = ui->instanceToolBar->actions(); + // reuse the file menu actions + actions = ui->fileMenu->actions(); - // replace the change icon widget with an actual action - actions.replace(0, ui->actionChangeInstIcon); + // remove the add instance action, launcher settings action and close action + actions.removeFirst(); + actions.removeLast(); + actions.removeLast(); - // replace the rename widget with an actual action - actions.replace(1, ui->actionRenameInstance); + actions.prepend(ui->actionChangeInstIcon); + actions.prepend(ui->actionRenameInstance); // add header actions.prepend(actionSep); @@ -1231,8 +554,6 @@ void MainWindow::updateMainToolBar() void MainWindow::updateToolsMenu() { - QToolButton *launchButton = dynamic_cast<QToolButton*>(ui->instanceToolBar->widgetForAction(ui->actionLaunchInstance)); - bool currentInstanceRunning = m_selectedInstance && m_selectedInstance->isRunning(); ui->actionLaunchInstance->setDisabled(!m_selectedInstance || currentInstanceRunning); @@ -1240,7 +561,6 @@ void MainWindow::updateToolsMenu() ui->actionLaunchInstanceDemo->setDisabled(!m_selectedInstance || currentInstanceRunning); QMenu *launchMenu = ui->actionLaunchInstance->menu(); - launchButton->setPopupMode(QToolButton::MenuButtonPopup); if (launchMenu) { launchMenu->clear(); @@ -1249,7 +569,6 @@ void MainWindow::updateToolsMenu() { launchMenu = new QMenu(this); } - QAction *normalLaunch = launchMenu->addAction(tr("Launch")); normalLaunch->setShortcut(QKeySequence::Open); QAction *normalLaunchOffline = launchMenu->addAction(tr("Launch Offline")); @@ -1358,7 +677,7 @@ void MainWindow::updateThemeMenu() void MainWindow::repopulateAccountsMenu() { accountMenu->clear(); - ui->profileMenu->clear(); + ui->accountsMenu->clear(); auto accounts = APPLICATION->accounts(); MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); @@ -1376,14 +695,10 @@ void MainWindow::repopulateAccountsMenu() if (accounts->count() <= 0) { - ui->all_actions.removeAll(&ui->actionNoAccountsAdded); - ui->actionNoAccountsAdded = TranslatedAction(this); - ui->actionNoAccountsAdded->setObjectName(QStringLiteral("actionNoAccountsAdded")); - ui->actionNoAccountsAdded.setTextId(QT_TRANSLATE_NOOP("MainWindow", "No accounts added!")); + ui->actionNoAccountsAdded->setText( "No accounts added!"); ui->actionNoAccountsAdded->setEnabled(false); accountMenu->addAction(ui->actionNoAccountsAdded); - ui->profileMenu->addAction(ui->actionNoAccountsAdded); - ui->all_actions.append(&ui->actionNoAccountsAdded); + ui->accountsMenu->addAction(ui->actionNoAccountsAdded); } else { @@ -1415,18 +730,17 @@ void MainWindow::repopulateAccountsMenu() } accountMenu->addAction(action); - ui->profileMenu->addAction(action); + ui->accountsMenu->addAction(action); connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); } } accountMenu->addSeparator(); - ui->profileMenu->addSeparator(); + ui->accountsMenu->addSeparator(); - ui->all_actions.removeAll(&ui->actionNoDefaultAccount); - ui->actionNoDefaultAccount = TranslatedAction(this); + ui->actionNoDefaultAccount = new QAction(this); ui->actionNoDefaultAccount->setObjectName(QStringLiteral("actionNoDefaultAccount")); - ui->actionNoDefaultAccount.setTextId(QT_TRANSLATE_NOOP("MainWindow", "No Default Account")); + ui->actionNoDefaultAccount->setText("No Default Account"); ui->actionNoDefaultAccount->setCheckable(true); ui->actionNoDefaultAccount->setIcon(APPLICATION->getThemedIcon("noaccount")); ui->actionNoDefaultAccount->setData(-1); @@ -1436,15 +750,13 @@ void MainWindow::repopulateAccountsMenu() } accountMenu->addAction(ui->actionNoDefaultAccount); - ui->profileMenu->addAction(ui->actionNoDefaultAccount); + ui->accountsMenu->addAction(ui->actionNoDefaultAccount); connect(ui->actionNoDefaultAccount, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); - ui->all_actions.append(&ui->actionNoDefaultAccount); - ui->actionNoDefaultAccount.retranslate(); accountMenu->addSeparator(); - ui->profileMenu->addSeparator(); + ui->accountsMenu->addSeparator(); accountMenu->addAction(ui->actionManageAccounts); - ui->profileMenu->addAction(ui->actionManageAccounts); + ui->accountsMenu->addAction(ui->actionManageAccounts); } void MainWindow::updatesAllowedChanged(bool allowed) @@ -1878,7 +1190,7 @@ void MainWindow::on_actionChangeInstIcon_triggered() m_selectedInstance->setIconKey(dlg.selectedIconKey); auto icon = APPLICATION->icons()->getIcon(dlg.selectedIconKey); ui->actionChangeInstIcon->setIcon(icon); - ui->changeIconButton->setIcon(icon); + changeIconButton->setIcon(icon); } } @@ -1888,7 +1200,7 @@ void MainWindow::iconUpdated(QString icon) { auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); - ui->changeIconButton->setIcon(icon); + changeIconButton->setIcon(icon); } } @@ -1897,7 +1209,7 @@ void MainWindow::updateInstanceToolIcon(QString new_icon) m_currentInstIcon = new_icon; auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); - ui->changeIconButton->setIcon(icon); + changeIconButton->setIcon(icon); } void MainWindow::setSelectedInstanceById(const QString &id) @@ -2145,6 +1457,7 @@ void MainWindow::closeEvent(QCloseEvent *event) // Save the window state and geometry. APPLICATION->settings()->set("MainWindowState", saveState().toBase64()); APPLICATION->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); + instanceToolbarSetting->set(ui->instanceToolBar->getVisibilityState()); event->accept(); emit isClosing(); } @@ -2378,7 +1691,7 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & if (m_selectedInstance) { ui->instanceToolBar->setEnabled(true); - ui->setInstanceActionsEnabled(true); + setInstanceActionsEnabled(true); ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch()); ui->actionLaunchInstanceOffline->setEnabled(m_selectedInstance->canLaunch()); ui->actionLaunchInstanceDemo->setEnabled(m_selectedInstance->canLaunch()); @@ -2391,7 +1704,7 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & ui->actionKillInstance->setEnabled(m_selectedInstance->isRunning()); ui->actionExportInstance->setEnabled(m_selectedInstance->canExport()); - ui->renameButton->setText(m_selectedInstance->name()); + renameButton->setText(m_selectedInstance->name()); m_statusLeft->setText(m_selectedInstance->getStatusbarDescription()); updateStatusCenter(); updateInstanceToolIcon(m_selectedInstance->iconKey()); @@ -2405,7 +1718,7 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & else { ui->instanceToolBar->setEnabled(false); - ui->setInstanceActionsEnabled(false); + setInstanceActionsEnabled(false); ui->actionLaunchInstance->setEnabled(false); ui->actionLaunchInstanceOffline->setEnabled(false); ui->actionLaunchInstanceDemo->setEnabled(false); @@ -2438,9 +1751,9 @@ void MainWindow::selectionBad() statusBar()->clearMessage(); ui->instanceToolBar->setEnabled(false); - ui->setInstanceActionsEnabled(false); + setInstanceActionsEnabled(false); updateToolsMenu(); - ui->renameButton->setText(tr("Rename Instance")); + renameButton->setText(tr("Rename Instance")); updateInstanceToolIcon("grass"); // ...and then see if we can enable the previously selected instance @@ -2495,6 +1808,18 @@ void MainWindow::updateStatusCenter() m_statusCenter->setText(tr("Total playtime: %1").arg(Time::prettifyDuration(timePlayed))); } } +// "Instance actions" are actions that require an instance to be selected (i.e. "new instance" is not here) +// Actions that also require other conditions (e.g. a running instance) won't be changed. +void MainWindow::setInstanceActionsEnabled(bool enabled) +{ + ui->actionEditInstance->setEnabled(enabled); + ui->actionChangeInstGroup->setEnabled(enabled); + ui->actionViewSelectedInstFolder->setEnabled(enabled); + ui->actionExportInstance->setEnabled(enabled); + ui->actionDeleteInstance->setEnabled(enabled); + ui->actionCopyInstance->setEnabled(enabled); + ui->actionCreateInstanceShortcut->setEnabled(enabled); +} void MainWindow::refreshCurrentInstance(bool running) { diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 84b5325a..fab21a8f 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -61,13 +61,16 @@ class BaseProfilerFactory; class InstanceView; class KonamiCode; class InstanceTask; +class LabeledToolButton; +namespace Ui +{ +class MainWindow; +} class MainWindow : public QMainWindow { Q_OBJECT - class Ui; - public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); @@ -107,10 +110,6 @@ private slots: void on_actionChangeInstGroup_triggered(); void on_actionChangeInstIcon_triggered(); - void on_changeIconButton_clicked(bool) - { - on_actionChangeInstIcon_triggered(); - } void on_actionViewInstanceFolder_triggered(); @@ -156,10 +155,6 @@ private slots: void on_actionExportInstance_triggered(); void on_actionRenameInstance_triggered(); - void on_renameButton_clicked(bool) - { - on_actionRenameInstance_triggered(); - } void on_actionEditInstance_triggered(); @@ -230,14 +225,14 @@ private: void updateInstanceToolIcon(QString new_icon); void setSelectedInstanceById(const QString &id); void updateStatusCenter(); + void setInstanceActionsEnabled(bool enabled); void runModalTask(Task *task); void instanceFromInstanceTask(InstanceTask *task); void finalizeInstance(InstancePtr inst); private: - std::unique_ptr<Ui> ui; - + Ui::MainWindow *ui; // these are managed by Qt's memory management model! InstanceView *view = nullptr; InstanceProxyModel *proxymodel = nullptr; @@ -245,9 +240,14 @@ private: QLabel *m_statusLeft = nullptr; QLabel *m_statusCenter = nullptr; QMenu *accountMenu = nullptr; + LabeledToolButton *changeIconButton = nullptr; + LabeledToolButton *renameButton = nullptr; QToolButton *accountMenuButton = nullptr; + QToolButton *helpMenuButton = nullptr; KonamiCode * secretEventFilter = nullptr; + std::shared_ptr<Setting> instanceToolbarSetting = nullptr; + unique_qobject_ptr<NewsChecker> m_newsChecker; InstancePtr m_selectedInstance; diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui new file mode 100644 index 00000000..6078ecbf --- /dev/null +++ b/launcher/ui/MainWindow.ui @@ -0,0 +1,697 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + </layout> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <widget class="QToolBar" name="mainToolBar"> + <property name="windowTitle"> + <string>Main Toolbar</string> + </property> + <property name="allowedAreas"> + <set>Qt::BottomToolBarArea|Qt::TopToolBarArea</set> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextBesideIcon</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionAddInstance"/> + <addaction name="separator"/> + <addaction name="actionFoldersButton"/> + <addaction name="actionSettings"/> + <addaction name="actionHelpButton"/> + <addaction name="actionCheckUpdate"/> + <addaction name="separator"/> + <addaction name="actionCAT"/> + <addaction name="actionAccountsButton"/> + </widget> + <widget class="QToolBar" name="newsToolBar"> + <property name="windowTitle"> + <string>News Toolbar</string> + </property> + <property name="allowedAreas"> + <set>Qt::BottomToolBarArea|Qt::TopToolBarArea</set> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextBesideIcon</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>BottomToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionNewsLabel"/> + <addaction name="actionMoreNews"/> + </widget> + <widget class="WideBar" name="instanceToolBar"> + <property name="windowTitle"> + <string>Instance Toolbar</string> + </property> + <property name="allowedAreas"> + <set>Qt::LeftToolBarArea|Qt::RightToolBarArea</set> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextBesideIcon</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>RightToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionLaunchInstance"/> + <addaction name="actionKillInstance"/> + <addaction name="separator"/> + <addaction name="actionEditInstance"/> + <addaction name="actionChangeInstGroup"/> + <addaction name="actionViewSelectedInstFolder"/> + <addaction name="actionExportInstance"/> + <addaction name="actionCopyInstance"/> + <addaction name="actionDeleteInstance"/> + <addaction name="actionCreateInstanceShortcut"/> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>20</height> + </rect> + </property> + <widget class="QMenu" name="fileMenu"> + <property name="title"> + <string>&File</string> + </property> + <property name="toolTipsVisible"> + <bool>true</bool> + </property> + <addaction name="actionAddInstance"/> + <addaction name="separator"/> + <addaction name="actionLaunchInstance"/> + <addaction name="actionKillInstance"/> + <addaction name="separator"/> + <addaction name="actionEditInstance"/> + <addaction name="actionChangeInstGroup"/> + <addaction name="actionViewSelectedInstFolder"/> + <addaction name="actionExportInstance"/> + <addaction name="actionCopyInstance"/> + <addaction name="actionDeleteInstance"/> + <addaction name="actionCreateInstanceShortcut"/> + <addaction name="separator"/> + <addaction name="actionSettings"/> + <addaction name="actionCloseWindow"/> + </widget> + <widget class="QMenu" name="editMenu"> + <property name="title"> + <string>&Edit</string> + </property> + <property name="toolTipsVisible"> + <bool>true</bool> + </property> + <addaction name="actionUndoTrashInstance"/> + </widget> + <widget class="QMenu" name="viewMenu"> + <property name="title"> + <string>&View</string> + </property> + <property name="toolTipsVisible"> + <bool>true</bool> + </property> + <addaction name="actionChangeTheme"/> + <addaction name="separator"/> + <addaction name="actionCAT"/> + <addaction name="actionLockToolbars"/> + <addaction name="separator"/> + </widget> + <widget class="QMenu" name="foldersMenu"> + <property name="title"> + <string>F&olders</string> + </property> + <property name="toolTipsVisible"> + <bool>true</bool> + </property> + <addaction name="actionViewInstanceFolder"/> + <addaction name="actionViewCentralModsFolder"/> + </widget> + <widget class="QMenu" name="accountsMenu"> + <property name="title"> + <string>&Accounts</string> + </property> + </widget> + <widget class="QMenu" name="helpMenu"> + <property name="title"> + <string>&Help</string> + </property> + <property name="toolTipsVisible"> + <bool>true</bool> + </property> + <addaction name="actionClearMetadata"/> + <addaction name="actionReportBug"/> + <addaction name="actionAddToPATH"/> + <addaction name="separator"/> + <addaction name="actionMATRIX"/> + <addaction name="actionDISCORD"/> + <addaction name="actionREDDIT"/> + <addaction name="separator"/> + <addaction name="actionMoreNews"/> + <addaction name="actionCheckUpdate"/> + <addaction name="actionOpenWiki"/> + <addaction name="actionAbout"/> + </widget> + <addaction name="fileMenu"/> + <addaction name="editMenu"/> + <addaction name="viewMenu"/> + <addaction name="foldersMenu"/> + <addaction name="accountsMenu"/> + <addaction name="helpMenu"/> + </widget> + <action name="actionNewsLabel"> + <property name="icon"> + <iconset theme="news"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>News</string> + </property> + </action> + <action name="actionMoreNews"> + <property name="icon"> + <iconset theme="news"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>More news...</string> + </property> + <property name="toolTip"> + <string>Open the development blog to read more news about %1.</string> + </property> + </action> + <action name="actionCAT"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset theme="cat"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Meow</string> + </property> + <property name="toolTip"> + <string>It's a fluffy kitty :3</string> + </property> + </action> + <action name="actionLockToolbars"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Lock Toolbars</string> + </property> + </action> + <action name="actionUndoTrashInstance"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Undo Last Instance Deletion</string> + </property> + </action> + <action name="actionAddInstance"> + <property name="icon"> + <iconset theme="new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Add Instanc&e...</string> + </property> + <property name="toolTip"> + <string>Add a new instance.</string> + </property> + </action> + <action name="actionCheckUpdate"> + <property name="icon"> + <iconset theme="checkupdate"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Update...</string> + </property> + <property name="toolTip"> + <string>Check for new updates for %1.</string> + </property> + <property name="menuRole"> + <enum>QAction::ApplicationSpecificRole</enum> + </property> + </action> + <action name="actionSettings"> + <property name="icon"> + <iconset theme="settings"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Setti&ngs...</string> + </property> + <property name="toolTip"> + <string>Change settings.</string> + </property> + <property name="menuRole"> + <enum>QAction::PreferencesRole</enum> + </property> + </action> + <action name="actionManageAccounts"> + <property name="icon"> + <iconset theme="accounts"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Manage Accounts...</string> + </property> + </action> + <action name="actionLaunchInstance"> + <property name="icon"> + <iconset theme="launch"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Launch</string> + </property> + <property name="toolTip"> + <string>Launch the selected instance.</string> + </property> + </action> + <action name="actionKillInstance"> + <property name="icon"> + <iconset theme="status-bad"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Kill</string> + </property> + <property name="toolTip"> + <string>Kill the running instance</string> + </property> + <property name="shortcut"> + <string>Ctrl+K</string> + </property> + </action> + <action name="actionRenameInstance"> + <property name="icon"> + <iconset theme="rename"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Rename</string> + </property> + <property name="toolTip"> + <string>Rename the selected instance.</string> + </property> + </action> + <action name="actionChangeInstGroup"> + <property name="icon"> + <iconset theme="tag"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Change Group...</string> + </property> + <property name="toolTip"> + <string>Change the selected instance's group.</string> + </property> + <property name="shortcut"> + <string>Ctrl+G</string> + </property> + </action> + <action name="actionChangeInstIcon"> + <property name="text"> + <string>Change Icon</string> + </property> + <property name="toolTip"> + <string>Change the selected instance's icon.</string> + </property> + </action> + <action name="actionEditInstance"> + <property name="icon"> + <iconset theme="settings"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + <property name="toolTip"> + <string>Change the instance settings, mods and versions.</string> + </property> + <property name="shortcut"> + <string>Ctrl+I</string> + </property> + </action> + <action name="actionViewSelectedInstFolder"> + <property name="icon"> + <iconset theme="viewfolder"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Folder</string> + </property> + <property name="toolTip"> + <string>Open the selected instance's root folder in a file browser.</string> + </property> + </action> + <action name="actionDeleteInstance"> + <property name="icon"> + <iconset theme="delete"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Dele&te</string> + </property> + <property name="toolTip"> + <string>Delete the selected instance.</string> + </property> + <property name="autoRepeat"> + <bool>false</bool> + </property> + </action> + <action name="actionCopyInstance"> + <property name="icon"> + <iconset theme="copy"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Cop&y...</string> + </property> + <property name="toolTip"> + <string>Copy the selected instance.</string> + </property> + <property name="shortcut"> + <string>Ctrl+D</string> + </property> + </action> + <action name="actionLaunchInstanceOffline"> + <property name="text"> + <string>Launch &Offline</string> + </property> + <property name="toolTip"> + <string>Launch the selected instance in offline mode.</string> + </property> + </action> + <action name="actionLaunchInstanceDemo"> + <property name="text"> + <string>Launch &Demo</string> + </property> + <property name="toolTip"> + <string>Launch the selected instance in demo mode.</string> + </property> + </action> + <action name="actionExportInstance"> + <property name="icon"> + <iconset theme="export"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>E&xport...</string> + </property> + <property name="toolTip"> + <string>Export the selected instance as a zip file.</string> + </property> + <property name="shortcut"> + <string>Ctrl+E</string> + </property> + </action> + <action name="actionCreateInstanceShortcut"> + <property name="icon"> + <iconset theme="shortcut"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Create Shortcut</string> + </property> + <property name="toolTip"> + <string>Creates a shortcut on your desktop to launch the selected instance.</string> + </property> + </action> + <action name="actionNoAccountsAdded"> + <property name="icon"> + <iconset theme="noaccount"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>No accounts added!</string> + </property> + </action> + <action name="actionNoDefaultAccount"> + <property name="icon"> + <iconset theme="noaccount"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>No Default Account</string> + </property> + </action> + <action name="actionCloseWindow"> + <property name="icon"> + <iconset theme="status-bad"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Close &Window</string> + </property> + <property name="toolTip"> + <string>Close the current window</string> + </property> + <property name="menuRole"> + <enum>QAction::QuitRole</enum> + </property> + </action> + <action name="actionViewInstanceFolder"> + <property name="icon"> + <iconset theme="viewfolder"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&View Instance Folder</string> + </property> + <property name="toolTip"> + <string>Open the instance folder in a file browser.</string> + </property> + </action> + <action name="actionViewCentralModsFolder"> + <property name="icon"> + <iconset theme="centralmods"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>View &Central Mods Folder</string> + </property> + <property name="toolTip"> + <string>Open the central mods folder in a file browser.</string> + </property> + </action> + <action name="actionChangeTheme"> + <property name="text"> + <string>Themes</string> + </property> + </action> + <action name="actionReportBug"> + <property name="icon"> + <iconset theme="bug"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Report a &Bug...</string> + </property> + <property name="toolTip"> + <string>Open the bug tracker to report a bug with %1.</string> + </property> + </action> + <action name="actionDISCORD"> + <property name="icon"> + <iconset theme="discord"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Discord Guild</string> + </property> + <property name="toolTip"> + <string>Open %1 Discord guild.</string> + </property> + </action> + <action name="actionMATRIX"> + <property name="icon"> + <iconset theme="matrix"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Matrix Space</string> + </property> + <property name="toolTip"> + <string>Open %1 Matrix space</string> + </property> + </action> + <action name="actionREDDIT"> + <property name="icon"> + <iconset theme="reddit-alien"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Sub&reddit</string> + </property> + <property name="toolTip"> + <string>Open %1 subreddit.</string> + </property> + </action> + <action name="actionAbout"> + <property name="icon"> + <iconset theme="about"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&About %1</string> + </property> + <property name="toolTip"> + <string>View information about %1.</string> + </property> + <property name="menuRole"> + <enum>QAction::AboutRole</enum> + </property> + </action> + <action name="actionClearMetadata"> + <property name="icon"> + <iconset theme="refresh"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>&Clear Metadata Cache</string> + </property> + <property name="toolTip"> + <string>Clear cached metadata</string> + </property> + </action> + <action name="actionAddToPATH"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="icon"> + <iconset theme="custom-commands"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Install to &PATH</string> + </property> + <property name="toolTip"> + <string>Install a %1 symlink to /usr/local/bin</string> + </property> + <property name="visible"> + <bool>false</bool> + </property> + </action> + <action name="actionFoldersButton"> + <property name="icon"> + <iconset theme="viewfolder"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Folders</string> + </property> + <property name="toolTip"> + <string>Open one of the folders shared between instances.</string> + </property> + </action> + <action name="actionHelpButton"> + <property name="icon"> + <iconset theme="help"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Help</string> + </property> + <property name="toolTip"> + <string>Get help with %1 or Minecraft.</string> + </property> + </action> + <action name="actionAccountsButton"> + <property name="icon"> + <iconset theme="noaccount"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Accounts</string> + </property> + </action> + <action name="actionOpenWiki"> + <property name="icon"> + <iconset theme="help"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>%1 &Help</string> + </property> + <property name="toolTip"> + <string>Open the %1 wiki</string> + </property> + </action> + </widget> + <customwidgets> + <customwidget> + <class>WideBar</class> + <extends>QToolBar</extends> + <header>ui/widgets/WideBar.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/launcher/ui/widgets/WideBar.cpp b/launcher/ui/widgets/WideBar.cpp index cee2038f..a029b0a8 100644 --- a/launcher/ui/widgets/WideBar.cpp +++ b/launcher/ui/widgets/WideBar.cpp @@ -10,6 +10,9 @@ class ActionButton : public QToolButton { ActionButton(QAction* action, QWidget* parent = nullptr) : QToolButton(parent), m_action(action) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + // workaround for breeze and breeze forks + setProperty("_kde_toolButton_alignment", Qt::AlignLeft); connect(action, &QAction::changed, this, &ActionButton::actionChanged); connect(this, &ActionButton::clicked, action, &QAction::trigger); @@ -21,6 +24,10 @@ class ActionButton : public QToolButton { { setEnabled(m_action->isEnabled()); setChecked(m_action->isChecked()); + setMenu(m_action->menu()); + if (menu()) { + setPopupMode(QToolButton::MenuButtonPopup); + } setCheckable(m_action->isCheckable()); setText(m_action->text()); setIcon(m_action->icon()); |