#include "client.h" #include "clicklabel.h" #include "audio.h" #include "util.h" #include "pacman.pb.h" extern "C" { #include "enet/enet.h" } Client::Client() : m_ambientMuted(false) { m_settings = new QSettings(qApp->organizationName(), qApp->applicationName(), this); m_dialog = new QDialog(this); m_mainWidget = new MainWidget(this); createMenu(); m_mainWidget->setAmbientMuted(m_ambientMuted); setCentralWidget(m_mainWidget); showConnectDialog(); m_dialog->setFocus(); } void Client::createMenu() { QMenu *fileMenu = menuBar()->addMenu("&File"); bool sound = AudioManager::self()->isWorking(); bool muted = !sound || m_settings->value("muted", false).toBool(); AudioManager::self()->setMuted(muted); /* toggle sound: corner icon */ ClickLabel *toggleSound = new ClickLabel("Toggle Sound", this); toggleSound->setToolTip("Toggle Sound"); toggleSound->setFixedWidth(20); toggleSound->setFixedHeight(16); toggleSound->setAlignment(Qt::AlignBottom); toggleSound->setPixmap(soundIcon(!muted)); if (sound) { connect(toggleSound, SIGNAL(clicked()), this, SLOT(toggleSound())); connect(AudioManager::self(), SIGNAL(mutedChanged(bool)), this, SLOT(mutedChanged(bool))); } menuBar()->setCornerWidget(toggleSound); /* toggle sound: menu */ QAction *toggleSoundAction = new QAction("&Sound", this); toggleSoundAction->setToolTip("Toggle Sound"); toggleSoundAction->setCheckable(true); toggleSoundAction->setChecked(!muted); toggleSoundAction->setDisabled(!sound); fileMenu->addAction(toggleSoundAction); if (sound) { connect(toggleSoundAction, SIGNAL(triggered()), this, SLOT(toggleSound())); connect(this, SIGNAL(setMuteActionsChecked(bool)), toggleSoundAction, SLOT(setChecked(bool))); } /* toggle ambient sound: menu */ m_ambientMuted = muted || m_settings->value("ambientMuted", false).toBool(); QAction *toggleAmbientAction = new QAction("&Ambient Sound", this); toggleAmbientAction->setToolTip("Toggle Ambient Sound"); toggleAmbientAction->setCheckable(true); toggleAmbientAction->setChecked(!m_ambientMuted); toggleAmbientAction->setDisabled(muted); fileMenu->addAction(toggleAmbientAction); if (sound) { connect(toggleAmbientAction, SIGNAL(triggered(bool)), this, SLOT(enableAmbientSound(bool))); connect(this, SIGNAL(setMuteActionsChecked(bool)), toggleAmbientAction, SLOT(setEnabled(bool))); } /* connect/disconnect entry */ fileMenu->addSeparator(); QAction *connectAction = new QAction("C&onnect", this); fileMenu->addAction(connectAction); connect(connectAction, SIGNAL(triggered()), this, SLOT(showConnectDialog())); connect(m_mainWidget, SIGNAL(connected(bool)), connectAction, SLOT(setDisabled(bool))); QAction *disconnectAction = new QAction("Di&sconnect", this); disconnectAction->setDisabled(true); fileMenu->addAction(disconnectAction); connect(disconnectAction, SIGNAL(triggered()), m_mainWidget, SLOT(doDisconnect())); connect(m_mainWidget, SIGNAL(connected(bool)), disconnectAction, SLOT(setEnabled(bool))); /* exit entry */ fileMenu->addSeparator(); QAction *quitAction = new QAction("E&xit", this); quitAction->setIcon(QIcon::fromTheme(QLatin1String("application-exit"))); fileMenu->addAction(quitAction); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); QAction *aboutAction= menuBar()->addAction("Ab&out"); connect(aboutAction, SIGNAL(triggered()), this, SLOT(showAbout())); } void Client::toggleSound() { if (!AudioManager::self()->isWorking()) return; bool muted = !AudioManager::self()->isMuted(); AudioManager::self()->setMuted(muted); /* mute ambient sound again if explicitly muted */ if (!muted && m_ambientMuted) m_mainWidget->setAmbientMuted(true); } void Client::mutedChanged(bool muted) { ClickLabel *tmp = qobject_cast(menuBar()->cornerWidget()); tmp->setPixmap(soundIcon(!muted)); m_settings->setValue("muted", muted); emit setMuteActionsChecked(!muted); } void Client::enableAmbientSound(bool enabled) { if (!AudioManager::self()->isWorking()) return; m_ambientMuted = !enabled; m_mainWidget->setAmbientMuted(m_ambientMuted); m_settings->setValue("ambientMuted", m_ambientMuted); } QPixmap Client::soundIcon(bool enabled) const { QImage img(enabled ? ":/soundon" : ":/soundoff"); img.setColor(1, menuBar()->palette().color( enabled ? QPalette::Active : QPalette::Disabled, QPalette::ButtonText).rgba()); return QPixmap::fromImage(img); } void Client::showAbout() { if (m_dialog != NULL) { delete m_dialog; m_dialog = new QDialog(this); } m_dialog->setWindowTitle("About Pacman"); m_dialog->setWindowFlags(m_dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint); QGridLayout *layout = new QGridLayout(m_dialog); layout->setSizeConstraint(QLayout::SetFixedSize); QString actoricons; for(int i = 0; Color::order[i] != Color::none; ++i) actoricons += QString("").arg(i + 1); const QString text = QString( "

Multiplayer Pacman %1

" "Authors: H. Demel, B. Mallinger, M. Mausz, M. Racz
" "
" "Gameplay based on Pacman" ", © Namco 1980
" "
" "Developed using Qt %2 (%3 bit)
") .arg(actoricons, QLatin1String(QT_VERSION_STR), QString::number(QSysInfo::WordSize)); QLabel *label = new QLabel(text, m_dialog); label->setWordWrap(true); label->setOpenExternalLinks(true); label->setTextInteractionFlags(Qt::TextBrowserInteraction); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, m_dialog); QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close); buttonBox->addButton(closeButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole | QDialogButtonBox::AcceptRole)); connect(buttonBox , SIGNAL(rejected()), m_dialog, SLOT(reject())); layout->addWidget(label, 0, 1, 4, 4); layout->addWidget(buttonBox, 4, 0, 1, 5); m_dialog->show(); } void Client::showConnectDialog() { if (m_dialog != NULL) { delete m_dialog; m_dialog = new QDialog(this); } m_dialog->setWindowTitle("Connect"); QGridLayout *layout = new QGridLayout(m_dialog); layout->setSizeConstraint(QLayout::SetFixedSize); QLabel *srvLabel = new QLabel("Address:", m_dialog); QLineEdit *srv = new QLineEdit(m_settings->value("address", "127.0.0.1").toString(), m_dialog); QLabel *portLabel = new QLabel("Port:", m_dialog); QDoubleSpinBox *port = new QDoubleSpinBox(m_dialog); port->setDecimals(0); port->setMinimum(1); port->setMaximum(65535); port->setValue(m_settings->value("port", Constants::Networking::port).toUInt()); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, m_dialog); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); QPushButton *cancelButton = buttonBox->button(QDialogButtonBox::Cancel); buttonBox->addButton(okButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::AcceptRole)); buttonBox->addButton(cancelButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole)); connect(buttonBox, SIGNAL(rejected()), m_dialog, SLOT(reject())); connect(buttonBox, SIGNAL(accepted()), m_dialog, SLOT(accept())); layout->addWidget(srvLabel, 0, 0); layout->addWidget(srv, 0, 1); layout->addWidget(portLabel, 1, 0); layout->addWidget(port, 1, 1); layout->addWidget(buttonBox, 4, 0, 1, 5); connect(m_dialog, SIGNAL(accepted()), this, SLOT(onAcceptConnectDialog())); m_dialog->show(); } void Client::onAcceptConnectDialog() { if (m_dialog == NULL) return; QGridLayout *layout = static_cast(m_dialog->layout()); QLineEdit *srv = static_cast(layout->itemAtPosition(0, 1)->widget()); QDoubleSpinBox *port = static_cast(layout->itemAtPosition(1, 1)->widget()); m_settings->setValue("address", srv->text()); m_settings->setValue("port", int(port->value())); m_mainWidget->doConnect(srv->text(), int(port->value())); } bool Constants::server = false; int main(int argc, char **argv) { /* Verify that the version of the library that we linked against is * compatible with the version of the headers we compiled against. */ GOOGLE_PROTOBUF_VERIFY_VERSION; if (enet_initialize () != 0) { qCritical() << "An error occurred while initializing ENet"; return EXIT_FAILURE; } Q_INIT_RESOURCE(pacman); QApplication app(argc, argv, true); app.setOrganizationName("TU Wien FOOP"); app.setApplicationName("Pacman Client"); app.setWindowIcon(QIcon(":/appicon")); qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); AudioManager::self(); Client client; client.show(); client.setWindowTitle(app.applicationName()); int ret = app.exec(); enet_deinitialize(); /* Delete all global objects allocated by libprotobuf */ google::protobuf::ShutdownProtobufLibrary(); return ret; }