/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - mainwindow.cpp * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Slougi * * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * This program 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 this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "mainwindow.h" #include "mainwidget.h" #include "globals.h" #include "rommodel.h" #include "settingsdialog.h" namespace core { extern "C" { #include "../gui.h" #include "../main.h" #include "../plugin.h" #include "../savestates.h" #include "../rom.h" #include "../config.h" } } MainWindow::MainWindow() : QMainWindow(0) , m_statusBarLabel(0) , m_uiActions(0) { setupUi(this); setupActions(); setState(core::GUI_STATE_STOPPED); m_statusBarLabel = new QLabel; statusBar()->addPermanentWidget(m_statusBarLabel); connect(mainWidget, SIGNAL(itemCountChanged(int)), this, SLOT(itemCountUpdate(int))); connect(mainWidget, SIGNAL(romDoubleClicked(QString, unsigned int)), this, SLOT(romOpen(QString, unsigned int))); QSize size(core::config_get_number("MainWindowWidth",600), core::config_get_number("MainWindowHeight",400)); QPoint position(core::config_get_number("MainWindowXPosition",0), core::config_get_number("MainWindowYPosition",0)); QDesktopWidget *d = QApplication::desktop(); QSize desktop = d->size(); if (position.x() > desktop.width()) { position.setX(0); } if (position.y() > desktop.height()) { position.setY(0); } if (size.width() > desktop.width()) { size.setWidth(600); } if (size.height() > desktop.height()) { size.setHeight(400); } if ((position.x() + size.width()) > desktop.width()) { position.setX(desktop.width() - size.width()); } if ((position.y()+size.height())>desktop.height()) { position.setY(desktop.height() - size.height()); } resize(size); move(position); } MainWindow::~MainWindow() { #ifdef __WIN32__ delete m_renderWindow; m_renderWindow = 0; #endif } void MainWindow::closeEvent(QCloseEvent *event) { Q_UNUSED(event); core::config_put_number("MainWindowWidth", width()); core::config_put_number("MainWindowHeight", height()); core::config_put_number("MainWindowXPosition", x()); core::config_put_number("MainWindowYPosition", y()); core::config_put_bool("StatusBarVisible", actionShowStatusbar->isChecked()); core::config_put_bool("ToolBarVisible", actionShowToolbar->isChecked()); core::config_put_bool("FilterVisible", actionShowFilter->isChecked()); #ifdef __WIN32__ if (m_renderWindow) { m_renderWindow->close(); m_renderWindow->deleteLater(); } #endif } #ifdef __WIN32__ bool MainWindow::eventFilter(QObject *obj, QEvent *ev) { if (obj == m_renderWindow) { switch (ev->type()) { case QEvent::Close: emulationStop(); return false; break; case QEvent::MouseButtonDblClick: actionFullScreen->toggle(); return true; break; case QEvent::KeyRelease: { QKeyEvent* qke = static_cast(ev); foreach (QObject* child, children()) { if (QAction*a = qobject_cast(child)) { QKeySequence seq(qke->key() + qke->modifiers()); if (seq == a->shortcut()) { a->activate(QAction::Trigger); } } } } return false; } } else { return QMainWindow::eventFilter(obj, ev); } } #endif void MainWindow::showInfoMessage(const QString& msg) { statusBar()->showMessage(msg); } void MainWindow::showAlertMessage(const QString& msg) { QMessageBox::critical(this, "Alert", msg); } bool MainWindow::confirmMessage(const QString& msg) { QMessageBox::StandardButton res; res = QMessageBox::question(this, tr("Confirm"), msg, QMessageBox::Yes | QMessageBox::No); switch (res) { case QMessageBox::Yes: return true; break; default: return false; break; } } void MainWindow::romOpen() { QString filter = RomExtensions.join(" "); QString filename = QFileDialog::getOpenFileName(this, tr("Select Rom"), QString(), filter); if (!filename.isEmpty()) { romOpen(filename, 0); } } void MainWindow::romOpen(const QString& url) { romOpen(url, 0); } void MainWindow::romOpen(const QString& url, unsigned int archivefile) { if (core::open_rom(url.toLocal8Bit(), archivefile) == 0) { startEmulation(); } } void MainWindow::romClose() { core::close_rom(); } void MainWindow::emulationStart() { if(!core::rom) { QModelIndex index = mainWidget->getRomBrowserIndex(); QString filename = index.data(RomModel::FullPath).toString(); unsigned int archivefile = index.data(RomModel::ArchiveFile).toUInt(); if (filename.isEmpty()) { if (confirmMessage(tr("There is no Rom loaded." \ " Do you want to load one?"))) { romOpen(); } return; } else { romOpen(filename, archivefile); } } else startEmulation(); } void MainWindow::emulationPauseContinue() { core::pauseContinueEmulation(); } void MainWindow::emulationStop() { core::stopEmulation(); #ifdef __WIN32__ if (m_renderWindow) { m_renderWindow->close(); m_renderWindow->deleteLater(); } #endif } void MainWindow::fullScreenToggle() { if(core::g_EmulatorRunning) core::changeWindow(); } void MainWindow::saveStateSave() { if (core::g_EmulatorRunning) { core::savestates_job |= SAVESTATE; } } void MainWindow::saveStateSaveAs() { if (core::g_EmulatorRunning) { QString filename = QFileDialog::getSaveFileName(this); if (!filename.isEmpty()) { core::savestates_select_filename(filename.toLocal8Bit()); core::savestates_job |= SAVESTATE; } } else { showAlertMessage(tr("Emulation not running!")); } } void MainWindow::saveStateLoad() { if (core::g_EmulatorRunning) { core::savestates_job |= LOADSTATE; } } void MainWindow::saveStateLoadFrom() { if (core::g_EmulatorRunning) { QString filename = QFileDialog::getOpenFileName(this); if (!filename.isEmpty()) { core::savestates_select_filename(filename.toLocal8Bit()); core::savestates_job |= LOADSTATE; } } else { showAlertMessage(tr("Emulation not running!")); } } void MainWindow::savestateCheckSlot() { int slot = core::savestates_get_slot(); foreach(QAction* a, slotActions) { a->setChecked(false); } if (slot >= 0 && slot < slotActions.count()) { QAction* a = slotActions.at(slot); a->setChecked(true); } } void MainWindow::savestateSelectSlot(QAction* a) { bool ok = false; int slot = a->data().toInt(&ok); if (ok) { core::savestates_select_slot(slot); } } //Slot should be renamed. void MainWindow::configDialogShow() { SettingsDialog* d = new SettingsDialog(this); d->exec(); } void MainWindow::itemCountUpdate(int count) { m_statusBarLabel->setText(tr("%n rom(s)", "", count)); } void MainWindow::aboutDialogShow() { QMessageBox::about(this, tr("About Mupen64Plus"), tr("Mupen64Plus N64 Emulator
\ Home...\ ")); } void MainWindow::customEvent(QEvent* event) { switch (event->type()) { case InfoEventType: showInfoMessage(static_cast(event)->message); break; case AlertEventType: showAlertMessage(static_cast(event)->message); break; default: qDebug("Got unknown custom event of type %d!", event->type()); break; } } void MainWindow::startEmulation() { #ifdef __WIN32__ m_renderWindow = new QWidget; m_renderWindow->addActions(actions()); m_renderWindow->installEventFilter(this); m_renderWindow->show(); core::g_RenderWindow = reinterpret_cast(m_renderWindow->winId()); core::g_StatusBar = reinterpret_cast(statusBar()->winId()); #endif core::startEmulation(); } void MainWindow::setupActions() { //File Actions actionOpenRom->setIcon(icon("mupen64cart.png")); connect(actionOpenRom, SIGNAL(triggered()), this, SLOT(romOpen())); actionCloseRom->setIcon(icon("edit-delete.png")); connect(actionCloseRom, SIGNAL(triggered()), this, SLOT(romClose())); actionQuit->setIcon(icon("dialog-error.png")); connect(actionQuit, SIGNAL(triggered()), this, SLOT(close())); //Emulation Actions actionStart->setIcon(icon("media-playback-start.png")); connect(actionStart, SIGNAL(triggered()), this, SLOT(emulationStart())); actionPause->setIcon(icon("media-playback-pause.png")); connect(actionPause, SIGNAL(triggered()), this, SLOT(emulationPauseContinue())); actionStop->setIcon(icon("media-playback-stop.png")); connect(actionStop, SIGNAL(triggered()), this, SLOT(emulationStop())); actionSaveState->setIcon(icon("document-save.png")); connect(actionSaveState, SIGNAL(triggered()), this, SLOT(saveStateSave())); actionLoadState->setIcon(icon("document-revert.png")); connect(actionLoadState, SIGNAL(triggered()), this, SLOT(saveStateLoad())); actionSaveStateAs->setIcon(icon("document-save-as.png")); connect(actionSaveStateAs, SIGNAL(triggered()), this, SLOT(saveStateSaveAs())); actionLoadStateFrom->setIcon(icon("document-open.png")); connect(actionLoadStateFrom, SIGNAL(triggered()), this, SLOT(saveStateLoadFrom())); actionCurrentSaveStateSlot->setIcon(icon("star.png")); QMenu* slotMenu = new QMenu(this); QActionGroup* slotActionGroup = new QActionGroup(actionCurrentSaveStateSlot); for(int i = 0; i < 10; i++) { QAction* slot = slotMenu->addAction(tr("Slot &%1").arg(i)); slot->setShortcut(QString("Ctrl+%1").arg(i)); slot->setCheckable(true); slot->setData(i); slotActionGroup->addAction(slot); slotActions << slot; } actionCurrentSaveStateSlot->setMenu(slotMenu); connect(slotMenu, SIGNAL(aboutToShow()), this, SLOT(savestateCheckSlot())); connect(slotActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(savestateSelectSlot(QAction*))); if (QWidget* w = toolBar->widgetForAction(actionCurrentSaveStateSlot)) { if (QToolButton* tb = qobject_cast(w)) { tb->setPopupMode(QToolButton::InstantPopup); } } //Settings Actions connect(actionShowFilter, SIGNAL(toggled(bool)), mainWidget, SLOT(showFilter(bool))); actionFullScreen->setIcon(icon("view-fullscreen.png")); connect(actionFullScreen, SIGNAL(triggered()), this, SLOT(fullScreenToggle())); actionConfigureMupen64Plus->setIcon(icon("preferences-system.png")); connect(actionConfigureMupen64Plus, SIGNAL(triggered()), this, SLOT(configDialogShow())); // Help menu actions actionAbout->setIcon(icon("mupen64plus.png")); connect(actionAbout, SIGNAL(triggered()), this, SLOT(aboutDialogShow())); connect(actionAboutQt, SIGNAL(triggered()), QApplication::instance(), SLOT(aboutQt())); actionShowToolbar->setChecked( core::config_get_bool("ToolBarVisible", TRUE) ); actionShowFilter->setChecked( core::config_get_bool("FilterVisible", TRUE) ); actionShowStatusbar->setChecked( core::config_get_bool("StatusBarVisible", TRUE) ); m_uiActions = new QActionGroup(this); m_uiActions->setExclusive(false); m_uiActions->addAction(actionCloseRom); m_uiActions->addAction(actionSaveState); m_uiActions->addAction(actionSaveStateAs); m_uiActions->addAction(actionLoadState); m_uiActions->addAction(actionLoadStateFrom); m_uiActions->addAction(actionFullScreen); m_uiActions->addAction(actionStop); m_uiActions->addAction(actionPause); } void MainWindow::setState(core::gui_state_t state) { bool pause, stop, play; pause = stop = play = false; switch (state) { case core::GUI_STATE_RUNNING: play = true; break; case core::GUI_STATE_PAUSED: pause = true; break; case core::GUI_STATE_STOPPED: stop = true; break; } m_uiActions->setEnabled(!stop); actionStart->setChecked(play); actionPause->setChecked(pause); actionStop->setChecked(stop); }