From 699a0ae8e39721d132920e4922dcb8be60e58751 Mon Sep 17 00:00:00 2001 From: Jon ESA Date: Wed, 1 Apr 2026 19:52:53 +0100 Subject: [PATCH] Added games picker and play/stop buttons --- GamesPanel.cpp | 74 ++++++++++++++++++++++++++++++++++++++------------ GamesPanel.h | 10 +++++-- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/GamesPanel.cpp b/GamesPanel.cpp index 62c6da7..458358a 100644 --- a/GamesPanel.cpp +++ b/GamesPanel.cpp @@ -9,7 +9,9 @@ #include // --------------------------------------------------------------------------- -// Helper: parse "GAM CODE1Name1 CODE2Name2 ..." → name->code map +// Helper: parse "GAM XXXXNAME1 XXXXNAME2 ..." +// Code is always the first 4 characters; remainder is the display name. +// "_S" sequences in the name are replaced with spaces. // --------------------------------------------------------------------------- static QMap parseGamResponse(const QString &response, const QString &subCmd) @@ -20,15 +22,11 @@ static QMap parseGamResponse(const QString &response, return result; for (const QString &entry : tokens.mid(2)) { - if (entry.isEmpty()) continue; - // First up-to-4 uppercase chars = code, remainder = name - int splitPos = 0; - while (splitPos < entry.size() && entry[splitPos].isUpper()) - ++splitPos; - const QString code = entry.left(qMin(splitPos, 4)); - QString name = entry.mid(code.size()); + if (entry.size() < 5) continue; // need at least 4-char code + 1-char name + const QString code = entry.left(4); + QString name = entry.mid(4); name.replace("_S", " "); - if (code.isEmpty() || name.isEmpty()) continue; + if (name.isEmpty()) continue; result[name] = code; } return result; @@ -44,7 +42,7 @@ GamesPanel::GamesPanel(QWidget *parent) : QWidget(parent) auto *splitter = new QSplitter(Qt::Horizontal, this); - // ---- Left pane: Available (not installed) games ---- + // ---- Left pane: Available (not yet installed) games ---- auto *leftWidget = new QWidget(splitter); auto *leftLayout = new QVBoxLayout(leftWidget); leftLayout->setContentsMargins(4, 4, 4, 4); @@ -61,19 +59,38 @@ GamesPanel::GamesPanel(QWidget *parent) : QWidget(parent) leftLayout->addWidget(m_availableList, 1); leftLayout->addWidget(m_addBtn); - // ---- Right pane: Installed games ---- + // ---- Right pane: Installed games + Start/Stop ---- auto *rightWidget = new QWidget(splitter); auto *rightLayout = new QVBoxLayout(rightWidget); rightLayout->setContentsMargins(4, 4, 4, 4); rightLayout->setSpacing(4); - auto *instLabel = new QLabel("Installed Games", rightWidget); + auto *instLabel = new QLabel("Installed Games", rightWidget); instLabel->setStyleSheet("color: #555;"); m_installedList = new QListWidget(rightWidget); m_installedList->addItem("Connect to load installed games..."); + // Start / Stop button row + auto *btnRow = new QHBoxLayout(); + m_startBtn = new QPushButton("▶ Start Game", rightWidget); + m_stopBtn = new QPushButton("■ Stop Game", rightWidget); + m_startBtn->setEnabled(false); + m_startBtn->setStyleSheet( + "QPushButton { color: white; background-color: #2e7d32;" + " border-radius: 4px; padding: 3px 10px; }" + "QPushButton:hover { background-color: #1b5e20; }" + "QPushButton:disabled { background-color: #888; color: #ccc; }"); + m_stopBtn->setStyleSheet( + "QPushButton { color: white; background-color: #c62828;" + " border-radius: 4px; padding: 3px 10px; }" + "QPushButton:hover { background-color: #b71c1c; }"); + btnRow->addWidget(m_startBtn); + btnRow->addWidget(m_stopBtn); + btnRow->addStretch(1); + rightLayout->addWidget(instLabel); rightLayout->addWidget(m_installedList, 1); + rightLayout->addLayout(btnRow); splitter->addWidget(leftWidget); splitter->addWidget(rightWidget); @@ -83,14 +100,22 @@ GamesPanel::GamesPanel(QWidget *parent) : QWidget(parent) layout->addWidget(splitter); - // Enable Add button only when something is selected in available list + // Enable Add only when available list has selection connect(m_availableList, &QListWidget::currentRowChanged, this, [this](int row) { m_addBtn->setEnabled(row >= 0); }); - connect(m_addBtn, &QPushButton::clicked, this, &GamesPanel::onAddClicked); + + // Enable Start only when installed list has selection + connect(m_installedList, &QListWidget::currentRowChanged, this, + [this](int row) { m_startBtn->setEnabled(row >= 0); }); + + connect(m_addBtn, &QPushButton::clicked, this, &GamesPanel::onAddClicked); + connect(m_startBtn, &QPushButton::clicked, this, &GamesPanel::onStartClicked); + connect(m_stopBtn, &QPushButton::clicked, this, + [this]() { emit commandRequested(QStringLiteral("GST")); }); } // --------------------------------------------------------------------------- -// Load installed games (GAM list response) +// Load installed games (GAM list response) // --------------------------------------------------------------------------- void GamesPanel::loadFromResponse(const QString &response) { @@ -98,11 +123,12 @@ void GamesPanel::loadFromResponse(const QString &response) m_installedList->clear(); for (const QString &name : m_installedGames.keys()) m_installedList->addItem(name); + m_startBtn->setEnabled(false); rebuildAvailable(); } // --------------------------------------------------------------------------- -// Load all available games (GAM listall response) +// Load full catalogue (GAM listall response) // --------------------------------------------------------------------------- void GamesPanel::loadAllFromResponse(const QString &response) { @@ -111,7 +137,7 @@ void GamesPanel::loadAllFromResponse(const QString &response) } // --------------------------------------------------------------------------- -// Rebuild available list = allGames minus installedGames (by code) +// Rebuild available list = allGames minus installedGames (matched by code) // --------------------------------------------------------------------------- void GamesPanel::rebuildAvailable() { @@ -128,7 +154,7 @@ void GamesPanel::rebuildAvailable() } // --------------------------------------------------------------------------- -// Add button clicked → emit GAM add +// Add selected available game to installed list // --------------------------------------------------------------------------- void GamesPanel::onAddClicked() { @@ -138,3 +164,15 @@ void GamesPanel::onAddClicked() if (!m_allGames.contains(name)) return; emit commandRequested(QString("GAM add %1").arg(m_allGames[name])); } + +// --------------------------------------------------------------------------- +// Start selected installed game: GST ,p +// --------------------------------------------------------------------------- +void GamesPanel::onStartClicked() +{ + auto *item = m_installedList->currentItem(); + if (!item) return; + const QString name = item->text(); + if (!m_installedGames.contains(name)) return; + emit commandRequested(QString("GST %1 ,p").arg(m_installedGames[name])); +} diff --git a/GamesPanel.h b/GamesPanel.h index 787feb0..4151570 100644 --- a/GamesPanel.h +++ b/GamesPanel.h @@ -13,21 +13,27 @@ class GamesPanel : public QWidget public: explicit GamesPanel(QWidget *parent = nullptr); void loadFromResponse(const QString &response); // GAM list (installed) - void loadAllFromResponse(const QString &response); // GAM listall (all available) + void loadAllFromResponse(const QString &response); // GAM listall (full catalogue) signals: void commandRequested(const QString &cmd); private slots: void onAddClicked(); + void onStartClicked(); private: void rebuildAvailable(); + // Left pane QListWidget *m_availableList = nullptr; - QListWidget *m_installedList = nullptr; QPushButton *m_addBtn = nullptr; + // Right pane + QListWidget *m_installedList = nullptr; + QPushButton *m_startBtn = nullptr; + QPushButton *m_stopBtn = nullptr; + QMap m_allGames; // name -> code (GAM listall) QMap m_installedGames; // name -> code (GAM list) };