1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
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.
|