This change's been unstaged since 2020 I think, it was probably just to test the idea of having a bottom grid acting as the general "database". It's working though it needs changing, I'm committing it and will modify it as needed in the future
154 lines
4.7 KiB
C++
154 lines
4.7 KiB
C++
/* Copyright 2020-2025, Michele Santullo
|
|
* This file is part of memoserv.
|
|
*
|
|
* Memoserv is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Memoserv is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Memoserv. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "memoserv_win.hpp"
|
|
#include "app_config.h"
|
|
#include "version_info_win.hpp"
|
|
#include "widgets/block_grid.hpp"
|
|
#include "memcard/memorycard.hpp"
|
|
#include "memcard/make_memory_card.hpp"
|
|
#include "make_qt_animation.hpp"
|
|
#include <QMenu>
|
|
#include <QMenuBar>
|
|
#include <QApplication>
|
|
#include <QFileDialog>
|
|
#include <QGridLayout>
|
|
#include <QLabel>
|
|
#include <QVBoxLayout>
|
|
#include <memory>
|
|
#include <filesystem>
|
|
#include <cassert>
|
|
|
|
class QApplication;
|
|
|
|
namespace duck {
|
|
namespace {
|
|
const constexpr int g_icon_size = 48;
|
|
const constexpr float g_icon_fps = 3.0f;
|
|
} //unnamed namespace
|
|
|
|
MemoservWin::MemoservWin(QApplication* app, QWidget *parent) :
|
|
QMainWindow(parent),
|
|
m_main_lay(nullptr),
|
|
m_lower_grid(nullptr),
|
|
m_grid_count(0)
|
|
{
|
|
auto vert_lay = std::make_unique<QVBoxLayout>();
|
|
{
|
|
m_main_lay = new QGridLayout;
|
|
vert_lay->addLayout(m_main_lay);
|
|
}
|
|
|
|
vert_lay->addWidget(m_lower_grid = new widget::BlockGrid(this, 0, 0, g_icon_fps));
|
|
m_lower_grid->set_icon_size(g_icon_size);
|
|
|
|
this->setCentralWidget(new QWidget);
|
|
this->centralWidget()->setLayout(vert_lay.release());
|
|
|
|
create_menu(app);
|
|
}
|
|
|
|
MemoservWin::~MemoservWin() noexcept = default;
|
|
|
|
void MemoservWin::create_menu(QApplication* app) {
|
|
QMenu* const file_menu = menuBar()->addMenu(tr("&File"));
|
|
{
|
|
const QIcon open_icon = QIcon::fromTheme("document-open", QIcon(":/images/open.png"));
|
|
const auto open_act = new QAction(open_icon, tr("&Open..."), this);
|
|
open_act->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_O));
|
|
connect(open_act, &QAction::triggered, this, &MemoservWin::open_file_from_dialog);
|
|
file_menu->addAction(open_act);
|
|
}
|
|
{
|
|
const QIcon quit_icon = QIcon::fromTheme("application-exit");
|
|
const auto quit_act = new QAction(quit_icon, tr("E&xit"), this);
|
|
quit_act->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
|
|
connect(quit_act, &QAction::triggered, [this](){this->close();});
|
|
file_menu->addAction(quit_act);
|
|
}
|
|
|
|
QMenu* const help_menu = menuBar()->addMenu(tr("&Help"));
|
|
{
|
|
const auto version_info_act = new QAction(tr("Version &info..."), this);
|
|
help_menu->addAction(version_info_act);
|
|
connect(version_info_act, &QAction::triggered, this, &MemoservWin::show_version_info);
|
|
}
|
|
{
|
|
help_menu->addAction(tr("About &Qt..."), app, &QApplication::aboutQt);
|
|
}
|
|
}
|
|
|
|
void MemoservWin::open_file_from_dialog() {
|
|
QStringList files = QFileDialog::getOpenFileNames(
|
|
this,
|
|
tr("Open memory card"),
|
|
QDir::homePath(),
|
|
tr("All supported formats") + " (*.mcr *.sav *.srm *.mcd);;" +
|
|
tr("ePSXe/PSEmu Pro Memory Card") + "(*.mcr);;" +
|
|
tr("Bleem! Memory Card") + "(*.mcd);;" +
|
|
tr("PCSX ReARMed/RetroArch") + "(*.srm);;" +
|
|
tr("All files") + " (*.*)",
|
|
nullptr,
|
|
QFileDialog::ReadOnly
|
|
);
|
|
load_memory_cards(files);
|
|
|
|
m_main_lay->setColumnStretch(m_grid_count, 1);
|
|
}
|
|
|
|
void MemoservWin::load_memory_cards (const QStringList& paths) {
|
|
using std::filesystem::path;
|
|
|
|
for (const auto& file : paths) {
|
|
auto lbl = std::make_unique<QLabel>();
|
|
|
|
lbl->setText(QString::fromStdString(path(file.toStdString()).filename()));
|
|
m_main_lay->setColumnStretch(m_grid_count, 0);
|
|
m_main_lay->addWidget(lbl.release(), 0, m_grid_count);
|
|
|
|
m_memcards.push_back(mc::psx::make_memory_card(file.toStdString()));
|
|
auto& mc = m_memcards.back();
|
|
auto grid = std::make_unique<widget::BlockGrid>(this, 5, 3, g_icon_fps);
|
|
grid->set_icon_size(g_icon_size);
|
|
|
|
std::vector<mc::psx::Block> blocks_for_db;
|
|
for (const auto& block : mc) {
|
|
blocks_for_db.reserve(block.block_count());
|
|
blocks_for_db.push_back(block);
|
|
if (blocks_for_db.size() == blocks_for_db.front().block_count()) {
|
|
m_block_db.add(blocks_for_db);
|
|
blocks_for_db.clear();
|
|
}
|
|
|
|
for (std::size_t n = 0; block.has_magic() and n < block.block_count(); ++n) {
|
|
grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
|
m_lower_grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
|
}
|
|
}
|
|
m_main_lay->addWidget(grid.release(), 1, m_grid_count);
|
|
|
|
++m_grid_count;
|
|
}
|
|
}
|
|
|
|
void MemoservWin::show_version_info() {
|
|
VersionInfoWin vinfo(this);
|
|
vinfo.setWindowModality(Qt::WindowModality::WindowModal);
|
|
vinfo.exec();
|
|
}
|
|
|
|
} //namespace duck
|