summaryrefslogtreecommitdiff
path: root/docs/handbook/meshmc/ui-system.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/handbook/meshmc/ui-system.md')
-rw-r--r--docs/handbook/meshmc/ui-system.md511
1 files changed, 511 insertions, 0 deletions
diff --git a/docs/handbook/meshmc/ui-system.md b/docs/handbook/meshmc/ui-system.md
new file mode 100644
index 0000000000..731cc68d54
--- /dev/null
+++ b/docs/handbook/meshmc/ui-system.md
@@ -0,0 +1,511 @@
+# UI System
+
+## Overview
+
+MeshMC's user interface is built on Qt6 Widgets. The UI follows a page-based navigation model, with a main window hosting instance management, and dialog-based workflows for settings, instance configuration, and account management.
+
+## Architecture
+
+### Key Classes
+
+| Class | File | Purpose |
+|---|---|---|
+| `MainWindow` | `ui/MainWindow.{h,cpp}` | Primary application window |
+| `InstanceWindow` | `ui/InstanceWindow.{h,cpp}` | Per-instance console window |
+| `PageDialog` | `ui/dialogs/PageDialog.{h,cpp}` | Dialog for page navigation |
+| `PageContainer` | `ui/pages/PageContainer.{h,cpp}` | Page management container |
+| `BasePage` | `ui/pages/BasePage.h` | Abstract page interface |
+| `InstanceView` | `ui/instanceview/InstanceView.{h,cpp}` | Grid/list instance view |
+| `WizardDialog` | `ui/setupwizard/SetupWizard.{h,cpp}` | First-run setup wizard |
+
+## MainWindow
+
+The central window of the application:
+
+```cpp
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(QWidget* parent = 0);
+ ~MainWindow();
+
+ // Instance management
+ void setSelectedInstanceById(const QString& id);
+
+ // Window state
+ void checkInstancePathForProblems();
+
+public slots:
+ void instanceActivated(QModelIndex);
+ void instanceChanged(const QModelIndex& current, const QModelIndex& previous);
+
+ // Toolbar actions
+ void on_actionAddInstance_triggered();
+ void on_actionViewSelectedInstFolder_triggered();
+ void on_actionViewSelectedMCFolder_triggered();
+ void on_actionCopyInstance_triggered();
+ void on_actionDeleteInstance_triggered();
+ void on_actionExportInstance_triggered();
+ void on_actionLaunchInstance_triggered();
+ void on_actionLaunchInstanceOffline_triggered();
+ void on_actionKillInstance_triggered();
+
+ // Global actions
+ void on_actionSettings_triggered();
+ void on_actionManageAccounts_triggered();
+ void on_actionAbout_triggered();
+ void on_actionCAT_triggered();
+
+ // Group management
+ void on_actionRenameGroup_triggered();
+ void on_actionDeleteGroup_triggered();
+
+private:
+ // UI components
+ Ui::MainWindow* ui;
+ InstanceView* view;
+ QToolBar* instanceToolbar;
+ QToolBar* newsToolbar;
+ StatusLabel* m_statusLeft;
+ StatusLabel* m_statusCenter;
+ QMenu* accountMenu;
+ QMenu* skinMenu;
+
+ // Models
+ InstanceProxyModel* proxymodel;
+ GroupView* groupView;
+
+ // State
+ MinecraftAccountPtr m_selectedAccount;
+ BaseInstance::Ptr m_selectedInstance;
+};
+```
+
+### Toolbar Layout
+
+The main window has two toolbars:
+
+**Main Toolbar:**
+| Action | Shortcut | Description |
+|---|---|---|
+| Add Instance | Ctrl+N | Opens NewInstanceDialog |
+| Folders | — | Dropdown: instances, central mods, skins |
+| Settings | — | Opens global settings dialog |
+| Help | — | About, bug report, wiki, Discord |
+| Update | — | Check for updates (when available) |
+
+**Instance Toolbar** (shown when an instance is selected):
+| Action | Description |
+|---|---|
+| Launch | Start the selected instance |
+| Launch Offline | Start without authentication |
+| Kill | Force-stop a running instance |
+| Edit Instance | Open instance settings |
+| Edit Mods | Open mod management page |
+| View Folder | Open instance folder in file manager |
+| Copy Instance | Duplicate the instance |
+| Delete | Delete the instance |
+| Export | Export instance as zip/mrpack |
+
+### Account Selector
+
+The account selector is a dropdown menu in the toolbar:
+- Shows current default account name + skin icon
+- Lists all accounts with switch option
+- "Manage Accounts..." opens global account settings
+- "No Default Account" option
+
+### Instance View
+
+`InstanceView` displays instances in a grid with grouping:
+
+```cpp
+class InstanceView : public QAbstractItemView
+{
+ Q_OBJECT
+public:
+ void setModel(QAbstractItemModel* model) override;
+
+ // View modes
+ void setIconSize(QSize size);
+
+signals:
+ void droppedURLs(QList<QUrl> urls);
+
+protected:
+ void paintEvent(QPaintEvent* event) override;
+ void mousePressEvent(QMouseEvent* event) override;
+ void mouseDoubleClickEvent(QMouseEvent* event) override;
+ void dragEnterEvent(QDragEnterEvent* event) override;
+ void dropEvent(QDropEvent* event) override;
+};
+```
+
+Features:
+- Custom grid layout with grouped headings
+- Drag-and-drop support for instance import (zip/mrpack files)
+- Custom icon rendering with play-time overlay
+- Context menu with all instance actions
+- Group collapse/expand
+
+## Page System
+
+### BasePage Interface
+
+All settings and configuration pages implement `BasePage`:
+
+```cpp
+class BasePage : public QWidget
+{
+public:
+ virtual ~BasePage() {}
+
+ virtual QString id() const = 0;
+ virtual QString displayName() const = 0;
+ virtual QIcon icon() const = 0;
+ virtual QString helpPage() const { return QString(); }
+ virtual bool shouldDisplay() const { return true; }
+
+ virtual void opened() {}
+ virtual void closed() {}
+ virtual bool apply() { return true; }
+
+ virtual bool isOpened() const { return m_isOpened; }
+
+protected:
+ bool m_isOpened = false;
+};
+```
+
+### PageContainer
+
+Manages page navigation with a tree-based sidebar:
+
+```cpp
+class PageContainer : public QWidget
+{
+ Q_OBJECT
+public:
+ PageContainer(BasePageProvider* pages, QString defaultId = QString(),
+ QWidget* parent = nullptr);
+
+ void setPageProvider(BasePageProvider* pages);
+ BasePage* getPage(const QString& id);
+ const QList<BasePage*>& getPages() const;
+
+ void selectPage(const QString& id);
+
+private:
+ QTreeView* m_pageList;
+ QStackedWidget* m_pageStack;
+ QList<BasePage*> m_pages;
+};
+```
+
+### PageDialog
+
+Wraps a `PageContainer` in a dialog:
+
+```cpp
+class PageDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ PageDialog(BasePageProvider* pages, QString title = QString(),
+ QWidget* parent = nullptr);
+
+ void accept() override;
+
+private:
+ PageContainer* m_container;
+};
+```
+
+Used for both global settings and instance settings.
+
+## Global Settings Pages
+
+### MeshMCPage
+- Update channel selection (stable/beta)
+- Auto-update toggle
+- Analytics opt-in/out
+- Instance sort mode
+
+### MinecraftPage
+- Default window dimensions (width × height)
+- Launch maximized toggle
+- Console visibility settings
+- Performance settings
+
+### JavaPage
+- Java path (manual or auto-detect)
+- Memory allocation (min/max heap)
+- JVM arguments
+- Java compatibility warnings toggle
+- "Auto-detect" button triggers `JavaUtils::FindJavaPaths()`
+- "Test" button verifies selected Java installation
+
+### LanguagePage
+- Language selector (populated from `translations/`)
+- Live preview of selected language
+
+### ProxyPage
+- Proxy type: None / SOCKS5 / HTTP
+- Proxy address, port
+- Authentication (username/password)
+
+### ExternalToolsPage
+- Profiler paths (JProfiler, JVisualVM, MCEdit)
+- Custom editor path
+
+### AccountListPage
+- Account list with status indicators
+- Add/Remove/Set Default/Refresh buttons
+- Skin preview panel
+
+### PasteEEPage
+- Paste service URL configuration
+
+### CustomCommandsPage
+- Pre-launch command
+- Wrapper command
+- Post-exit command
+
+### AppearancePage
+- Application theme selector
+- Icon theme selector
+- Cat style (cat/kitteh)
+
+## Instance Pages
+
+When editing an instance (`PageDialog` with instance pages):
+
+### VersionPage
+- Component list (Minecraft version, mod loaders)
+- Add/Remove/Change version of components
+- Component ordering (move up/down)
+
+### ModFolderPage
+- Mod list with enable/disable toggles
+- Add from file / Add from CurseForge / Add from Modrinth
+- Remove selected mods
+- View mod details
+
+### LogPage
+- Live log output from running instance
+- Search/filter log content
+- Upload to paste service
+- Copy to clipboard
+- Auto-scroll toggle
+
+### InstanceSettingsPage
+- Java override (checkbox + path)
+- Memory override (checkbox + min/max)
+- JVM args override
+- Window size override
+- Console settings override
+- Custom commands override
+
+### WorldListPage
+- List of worlds with metadata
+- Backup/Restore/Delete operations
+- Datapacks submenu
+
+### ScreenshotsPage
+- Grid view of instance screenshots
+- Open in file manager
+- Delete selected
+- Upload to Imgur
+
+### ResourcePackPage / TexturePackPage
+- Resource/texture pack list
+- Add/Remove
+- Enable/disable
+
+### NotesPage
+- Free-text notes field per instance
+
+### ServersPage
+- Server list for the instance
+- Add/Edit/Remove servers
+
+## Dialogs
+
+### NewInstanceDialog
+
+Multi-tab dialog for creating new instances:
+
+| Tab | Source |
+|---|---|
+| Vanilla | Select Minecraft version |
+| Import | Import from zip/mrpack URL or file |
+| CurseForge | Browse CurseForge modpacks |
+| Modrinth | Browse Modrinth modpacks |
+| ATLauncher | ATLauncher pack listing |
+| FTB | FTB pack listing |
+| Technic | Technic Platform packs |
+
+Each tab provides search, filtering, and version selection. On confirmation, the appropriate import/creation task is started.
+
+### CopyInstanceDialog
+
+Options for duplicating an instance:
+- New name
+- New group assignment
+- Copy saves (toggle)
+- Keep play time (toggle)
+
+### ExportInstanceDialog
+
+Export format selection and file exclusion:
+- Format: MeshMC zip / Modrinth mrpack / CurseForge manifest
+- File tree with checkboxes for selective export
+- Exclusion filter patterns
+
+### MSALoginDialog
+
+Microsoft account login flow (see Account Management):
+- Displays login URL with copy button
+- Shows authentication progress
+- Error display on failure
+
+### ProfileSelectDialog
+
+Account selection when no default is set:
+- Account list with radio selection
+- "Use selected" / Cancel
+
+### ProfileSetupDialog
+
+First-time Minecraft profile setup:
+- Username entry
+- Validates username availability
+- Creates profile via Mojang API
+
+### SkinUploadDialog
+
+Skin upload interface:
+- File picker for skin PNG
+- Variant selector (classic/slim)
+- Preview
+
+### AboutDialog
+
+Application information:
+- Version, build info, Qt version
+- License (GPL-3.0-or-later)
+- Credits and contributors
+
+### UpdateDialog
+
+Update notification:
+- Version comparison
+- Changelog display
+- Update / Skip buttons
+
+## Setup Wizard
+
+`SetupWizard` runs on first launch or when required:
+
+```cpp
+class SetupWizard : public QWizard
+{
+ Q_OBJECT
+public:
+ SetupWizard(QWidget* parent = nullptr);
+
+ // Pages added conditionally
+ void addLanguagePage();
+ void addJavaPage();
+ void addAnalyticsPage();
+ void addPasteEEPage();
+};
+```
+
+Pages are added based on what needs configuration:
+- **LanguagePage** — if no language is set
+- **JavaPage** — if no valid Java is detected
+- **AnalyticsPage** — if analytics consent is not recorded
+- **PasteEEPage** — if paste service is not configured
+
+## Widget Components
+
+### StatusLabel
+
+Custom label widget for the status bar:
+- Elides long text
+- Supports click-to-copy
+- Used for status area in MainWindow
+
+### InstanceDelegate
+
+Custom item delegate for `InstanceView`:
+- Renders instance icon, name, and status
+- Shows play time overlay
+- Running state indicator
+
+### ProgressWidget
+
+Shared progress display widget:
+- Progress bar with percentage
+- Status text label
+- Cancel button
+- Used by download dialogs, import tasks, etc.
+
+### IconPickerDialog
+
+Instance icon selection:
+- Built-in icon library
+- Custom icon upload
+- Icon theme integration
+
+## Event Handling
+
+### Instance Double-Click
+
+```
+MainWindow::instanceActivated(QModelIndex)
+ │
+ ├── If instance is running → open InstanceWindow
+ └── If instance is stopped → launch instance
+```
+
+### Instance Launch
+
+```
+MainWindow::on_actionLaunchInstance_triggered()
+ │
+ ├── Resolve account (default or prompt with ProfileSelectDialog)
+ ├── Create LaunchController
+ │ ├── Set instance, account, main window
+ │ └── connect succeeded/failed signals
+ └── LaunchController::start()
+```
+
+### Drag-and-Drop Import
+
+```
+InstanceView::dropEvent(QDropEvent)
+ │
+ ├── Extract URLs from QMimeData
+ ├── Filter for .zip, .mrpack files
+ └── For each URL → open NewInstanceDialog with import tab pre-selected
+```
+
+## Window Management
+
+`Application` manages window lifecycle:
+
+```cpp
+// Track open windows
+QList<QWidget*> m_openWindows;
+
+// Show instance window
+void Application::showInstanceWindow(InstancePtr instance);
+
+// Main window
+MainWindow* Application::showMainWindow();
+```
+
+Multiple windows can be open simultaneously (main window + instance console windows). The application exits when all windows are closed.