1 #include "gamemenu.h"
2 #include "gamescene.h"
3 #include "gameprofile.h"
4 #include "gamesound.h"
5 #include "gamewidget.h"
6 #include "helpform.h"
7
keyPressEvent(QKeyEvent * keyEvent)8 void MenuWidget::keyPressEvent(QKeyEvent *keyEvent)
9 {
10 if (isActive()) {
11 switch (keyEvent->key()) {
12 case Qt::Key_Escape: {
13 switch (currentIndex()) {
14 case MENU_MAIN:
15 on_bExit_clicked();
16 break;
17 case MENU_OPTIONS:
18 on_bOptBack_clicked();
19 break;
20 case MENU_PAUSE:
21 on_bPauseBack_clicked();
22 break;
23 case MENU_GRAPHICS:
24 on_bGraphicsBack_clicked();
25 break;
26 case MENU_AUDIO:
27 on_bAudioBack_clicked();
28 break;
29 case MENU_PROFILE:
30 on_bProfileBack_clicked();
31 break;
32 // case MENU_HALL:
33 // on_bHallBack_clicked();
34 // break;
35 case MENU_HELP:
36 on_bHelpBack_clicked();
37 break;
38 case MENU_CREDITS:
39 on_bCreditsBack_clicked();
40 break;
41 case MENU_LEVELS:
42 on_bLevelsBack_clicked();
43 break;
44 case MENU_LANGUAGE:
45 on_bLangBack_clicked();
46 break;
47 }
48 }
49 break;
50
51 }
52 keyEvent->accept();
53 }
54 }
55
56 ////////////////////////////////////////////////////////////////////////////////
on_bNew_clicked()57 void MenuWidget::on_bNew_clicked()
58 {
59 if (gameProfile->currentPlayer()->name.isEmpty()) {
60 // show profile select menu
61 startAfterSelect = true;
62 on_bOptProfile_clicked();
63 }
64 else {
65 // start new game
66 emit menuNew();
67 }
68 }
69
on_bContinue_clicked()70 void MenuWidget::on_bContinue_clicked()
71 {
72 emit menuContinue();
73 }
74
on_bOptions_clicked()75 void MenuWidget::on_bOptions_clicked()
76 {
77 setCurrentIndex(MENU_OPTIONS);
78 }
79
80 /*
81 void MenuWidget::on_bHall_clicked()
82 {
83 updateHallOfFame();
84 setCurrentIndex(MENU_HALL);
85 }
86 */
87
showHelp()88 void MenuWidget::showHelp()
89 {
90 int x = (WIDTH-helpForm->width())/2;
91 int y = (HEIGHT-helpForm->height())/2;
92 helpForm->move(x,y);
93 helpForm->exec();
94 }
95
on_bHelp_clicked()96 void MenuWidget::on_bHelp_clicked()
97 {
98 //setCurrentIndex(MENU_HELP);
99 showHelp();
100 }
101
on_bCredits_clicked()102 void MenuWidget::on_bCredits_clicked()
103 {
104 setCurrentIndex(MENU_CREDITS);
105 }
106
on_bExit_clicked()107 void MenuWidget::on_bExit_clicked()
108 {
109 emit menuExit();
110 }
111
on_bOptGraphics_clicked()112 void MenuWidget::on_bOptGraphics_clicked()
113 {
114 setCurrentIndex(MENU_GRAPHICS);
115
116 // set themes list
117 ui.lwThemes->clear();
118 ui.lwThemes->addItems(gameProfile->themesList());
119 QList<QListWidgetItem *> found = ui.lwThemes->findItems(gameProfile->currentTheme(), Qt::MatchFixedString);
120 if (found.count())
121 ui.lwThemes->setCurrentItem(found.at(0));
122 else
123 ui.lwThemes->setCurrentRow(0);
124
125 // set video mode
126 ui.cbFullscreenMode->setChecked(gameProfile->isFullscreen());
127
128 ui.cbAccel->setChecked(gameProfile->isAccelerated());
129
130 QString mode(QString("%1 x %2")
131 .arg(gameProfile->screenWidth())
132 .arg(gameProfile->screenHeight()));
133 QList<QListWidgetItem *> items = ui.lwVideoMode->findItems(mode, Qt::MatchExactly);
134 if (items.count())
135 ui.lwVideoMode->setCurrentItem(items.first());
136 }
137
on_bOptSound_clicked()138 void MenuWidget::on_bOptSound_clicked()
139 {
140 setCurrentIndex(MENU_AUDIO);
141
142 // sounds
143 ui.cbVolumeSound->setValue(gameProfile->currentPlayer()->soundVolume);
144 ui.cbMuteSound->setChecked(gameProfile->currentPlayer()->soundVolume == 0);
145
146 // music
147 ui.cbVolumeMusic->setValue(gameProfile->currentPlayer()->musicVolume);
148 ui.cbMuteMusic->setChecked(!gameProfile->currentPlayer()->musicEnabled);
149 }
150
on_bOptProfile_clicked()151 void MenuWidget::on_bOptProfile_clicked()
152 {
153 setCurrentIndex(MENU_PROFILE);
154 // set name edit
155 QString name = gameProfile->currentPlayer()->name;
156 //ui.leName->setText(name.isEmpty() ? tr("Player") : name);
157 // set users list
158 ui.lwPlayersList->clear();
159 ui.lwPlayersList->addItem(tr("[New Player]"));
160 ui.lwPlayersList->addItems(gameProfile->playerNames());
161
162 QList<QListWidgetItem *> found = ui.lwPlayersList->findItems(name, Qt::MatchFixedString);
163 if (found.count())
164 ui.lwPlayersList->setCurrentItem(found.at(0));
165 else
166 ui.lwPlayersList->setCurrentRow(0);
167 }
168
on_bOptLevels_clicked()169 void MenuWidget::on_bOptLevels_clicked()
170 {
171 setCurrentIndex(MENU_LEVELS);
172
173 // levels list
174 QStringList ext; ext << "*.lpk";
175 lpacks = QDir(GameWidget::getResourcePath() + "levels/").entryList(ext);
176 ui.lwLevels->clear();
177 for (int i = 0; i < lpacks.count(); i++) {
178 QString name = lpacks.at(i).section('.',0,0);
179 int cnt = gameProfile->levelPackCount(name);
180 QString packname = gameProfile->levelPackName(name);
181 ui.lwLevels->addItem(tr("%1 [%2 levels]").arg(packname).arg(cnt));
182 }
183
184 QList<QListWidgetItem *> found = ui.lwLevels->findItems(gameProfile->currentLevelPack(), Qt::MatchFixedString);
185 if (found.count())
186 ui.lwLevels->setCurrentItem(found.at(0));
187 else
188 ui.lwLevels->setCurrentRow(0);
189 }
190
on_bOptLanguage_clicked()191 void MenuWidget::on_bOptLanguage_clicked()
192 {
193 setCurrentIndex(MENU_LANGUAGE);
194
195 // languages list
196 ui.lwLanguage->clear();
197 ui.lwLanguage->addItem(LANG_DEFAULT);
198
199 QSettings settings("xlabsoft","chains");
200 QString lang = settings.value("Language", "").toString();
201 int index = 0;
202
203 QString langfile = GameWidget::getResourcePath() + "lang/langlist.dat";
204 QFile f(langfile);
205 if (!f.open(QFile::ReadOnly | QFile::Text))
206 return;
207 QTextStream ts(&f);
208
209 while (!ts.atEnd()) {
210 QString qs = ts.readLine().simplified();
211 QString langname = qs.section("::",0,0).simplified();
212 if (!langname.isEmpty()) {
213 ui.lwLanguage->addItem(langname);
214 qs = qs.section("::",1,1).simplified();
215 if (qs == lang)
216 index = ui.lwLanguage->count() - 1;
217 }
218 }
219 f.close();
220
221 ui.lwLanguage->setCurrentRow(index);
222 }
223
on_bOptBack_clicked()224 void MenuWidget::on_bOptBack_clicked()
225 {
226 setCurrentIndex(MENU_MAIN);
227 startAfterSelect = false;
228 }
229
on_bPauseGraphics_clicked()230 void MenuWidget::on_bPauseGraphics_clicked()
231 {
232 on_bOptGraphics_clicked();
233 }
234
on_bPauseSound_clicked()235 void MenuWidget::on_bPauseSound_clicked()
236 {
237 on_bOptSound_clicked();
238 }
239
on_bPauseHelp_clicked()240 void MenuWidget::on_bPauseHelp_clicked()
241 {
242 on_bHelp_clicked();
243 }
244
on_bPauseRestart_clicked()245 void MenuWidget::on_bPauseRestart_clicked()
246 {
247 emit menuRestartLevel();
248 }
249
on_bPauseAbandon_clicked()250 void MenuWidget::on_bPauseAbandon_clicked()
251 {
252 emit menuAbandonGame();
253 }
254
on_bPauseBack_clicked()255 void MenuWidget::on_bPauseBack_clicked()
256 {
257 emit menuPauseBack();
258 }
259
on_bGraphicsOk_clicked()260 void MenuWidget::on_bGraphicsOk_clicked()
261 {
262 // apply options
263 QListWidgetItem *lwi = ui.lwThemes->currentItem();
264 if (lwi) {
265 gameProfile->setCurrentTheme(lwi->text());
266 emit menuThemeChanged();
267 }
268
269
270 bool fs = ui.cbFullscreenMode->isChecked();
271
272 QString tmp, mode(ui.lwVideoMode->currentItem()->text());
273 int w,h; QTextStream ts(&mode); ts >> w >> tmp >> h;
274
275 if (fs != gameProfile->isFullscreen()
276 || w != gameProfile->screenWidth()
277 || h != gameProfile->screenHeight())
278 {
279 gameProfile->setFullscreen(fs);
280 gameProfile->setVideoMode(w,h);
281 emit menuVideoModeChanged();
282 }
283
284 bool acc = ui.cbAccel->isChecked();
285 if (acc != gameProfile->isAccelerated())
286 {
287 QMessageBox::information(nullptr, tr("Restart needed"),
288 tr("In order to enable or disable acceleration,\n please restart the game."),
289 QMessageBox::Close);
290 }
291 gameProfile->setAccelerated(acc);
292
293 on_bGraphicsBack_clicked();
294 }
295
on_bGraphicsBack_clicked()296 void MenuWidget::on_bGraphicsBack_clicked()
297 {
298 setCurrentIndex(gameProfile->isGameStarted() ? MENU_PAUSE : MENU_OPTIONS);
299 }
300
on_bAudioBack_clicked()301 void MenuWidget::on_bAudioBack_clicked()
302 {
303 setCurrentIndex(gameProfile->isGameStarted() ? MENU_PAUSE : MENU_OPTIONS);
304 }
305
on_cbVolumeMusic_valueChanged(int val)306 void MenuWidget::on_cbVolumeMusic_valueChanged(int val)
307 {
308 sndEngine->setMusicVolume(val);
309 gameProfile->currentPlayer()->musicVolume = val;
310 }
311
on_cbMuteMusic_toggled(bool on)312 void MenuWidget::on_cbMuteMusic_toggled(bool on)
313 {
314 sndEngine->enableMusic(!on);
315 gameProfile->currentPlayer()->musicEnabled = !on;
316
317 ui.cbVolumeMusic->setEnabled(!on);
318 }
319
on_cbVolumeSound_valueChanged(int val)320 void MenuWidget::on_cbVolumeSound_valueChanged(int val)
321 {
322 sndEngine->setChannelVolume(val);
323 gameProfile->currentPlayer()->soundVolume = val;
324
325 sndEngine->playSound(GameSound::sndBomb);
326 }
327
on_cbMuteSound_toggled(bool on)328 void MenuWidget::on_cbMuteSound_toggled(bool on)
329 {
330 ui.cbVolumeSound->setEnabled(!on);
331
332 if (on) {
333 sndEngine->setChannelVolume(0);
334 gameProfile->currentPlayer()->soundVolume = 0;
335 }
336 else {
337 on_cbVolumeSound_valueChanged(ui.cbVolumeSound->value());
338 gameProfile->currentPlayer()->soundVolume = ui.cbVolumeSound->value();
339 }
340 }
341
on_rbArcade_toggled(bool on)342 void MenuWidget::on_rbArcade_toggled(bool on)
343 {
344 gameProfile->currentPlayer()->currentLevelPackInfo()->mode = on ? 0 : 1;
345 }
346
on_rbPuzzle_toggled(bool on)347 void MenuWidget::on_rbPuzzle_toggled(bool on)
348 {
349 gameProfile->currentPlayer()->currentLevelPackInfo()->mode = on ? 1 : 0;
350 }
351
on_sliDifficulty_valueChanged(int val)352 void MenuWidget::on_sliDifficulty_valueChanged(int val)
353 {
354 gameProfile->currentPlayer()->currentLevelPackInfo()->diff = val;
355 QString qs;
356 switch (val) {
357 case 1: qs = tr("Easy"); break;
358 case 2: qs = tr("Normal"); break;
359 case 3: qs = tr("Hard"); break;
360 default: qs = "";
361 }
362 ui.labelDiff->setText(qs);
363 }
364
on_bGameStart_clicked()365 void MenuWidget::on_bGameStart_clicked()
366 {
367 LevelPackInfo *lpi = gameProfile->currentPlayer()->currentLevelPackInfo();
368 lpi->mode = ui.rbArcade->isChecked() ? 0 : 1;
369 lpi->diff = ui.sliDifficulty->value();
370
371 emit menuGameStart();
372 }
373
on_bProfileSelect_clicked()374 void MenuWidget::on_bProfileSelect_clicked()
375 {
376 if (ui.lwPlayersList->currentRow() == 0)
377 { // new player clicked
378 bool ok;
379 QString name = QInputDialog::getText(this, tr("New Player"), tr("Enter new Player name:"),
380 QLineEdit::Normal, tr("Player"), &ok,
381 Qt::FramelessWindowHint);
382 if (ok && !name.isEmpty())
383 {
384 QList<QListWidgetItem *> found = ui.lwPlayersList->findItems(name, Qt::MatchFixedString);
385 if (found.isEmpty()) {
386 ui.lwPlayersList->addItem(name);
387 ui.lwPlayersList->setCurrentRow(ui.lwPlayersList->count()-1);
388 gameProfile->setCurrentPlayer(name);
389 } else {
390 QMessageBox::critical(this, tr("Player exists"),
391 tr("Cannot create new Player with existing name!"));
392 }
393 }
394 }
395 else {
396 if (ui.lwPlayersList->currentItem()) {
397 QString name = ui.lwPlayersList->currentItem()->text();
398 if (!name.isEmpty()) {
399 // update video mode
400 bool fs = gameProfile->isFullscreen();
401 int w = gameProfile->screenWidth();
402 int h = gameProfile->screenHeight();
403
404 gameProfile->setCurrentPlayer(name);
405
406 if (fs != gameProfile->isFullscreen()
407 || w != gameProfile->screenWidth() || h != gameProfile->screenHeight())
408 emit menuVideoModeChanged();
409
410 // update sound settings
411 sndEngine->setChannelVolume(gameProfile->currentPlayer()->soundVolume);
412 sndEngine->setMusicVolume(gameProfile->currentPlayer()->musicVolume);
413 sndEngine->enableMusic(gameProfile->currentPlayer()->musicEnabled);
414
415 if (startAfterSelect)
416 emit menuNew();
417 else
418 on_bProfileBack_clicked();
419 }
420 }
421 }
422 }
423
on_bProfileRename_clicked()424 void MenuWidget::on_bProfileRename_clicked()
425 {
426 if (ui.lwPlayersList->currentRow() > 0)
427 {
428 bool ok;
429 QString name = QInputDialog::getText(this, tr("Rename Player"), tr("Change Player name:"),
430 QLineEdit::Normal, ui.lwPlayersList->currentItem()->text(), &ok,
431 Qt::FramelessWindowHint);
432 if (ok && !name.isEmpty())
433 {
434 QList<QListWidgetItem *> found = ui.lwPlayersList->findItems(name, Qt::MatchFixedString);
435 if (found.isEmpty()) {
436 gameProfile->renamePlayer(ui.lwPlayersList->currentItem()->text(), name);
437 ui.lwPlayersList->currentItem()->setText(name);
438 } else {
439 QMessageBox::critical(this, tr("Player exists"),
440 tr("Cannot rename to the existing name!"));
441 }
442 }
443 }
444 }
445
on_bProfileDelete_clicked()446 void MenuWidget::on_bProfileDelete_clicked()
447 {
448 if (ui.lwPlayersList->currentRow() <= 0) return;
449
450 if (QMessageBox::question(this, tr("Remove Player"),
451 tr("Are you sure to remove %1?").arg(ui.lwPlayersList->currentItem()->text()),
452 QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel)
453 return;
454
455 int row = ui.lwPlayersList->currentRow();
456 QListWidgetItem *item = ui.lwPlayersList->takeItem(row);
457 if (item) {
458 gameProfile->removePlayer(item->text());
459 delete item;
460 }
461 if (row > 0 && row < ui.lwPlayersList->count())
462 ui.lwPlayersList->setCurrentRow(row);
463
464 }
465
on_bProfileBack_clicked()466 void MenuWidget::on_bProfileBack_clicked()
467 {
468 setCurrentIndex(MENU_OPTIONS);
469 }
470
on_lwPlayersList_itemDoubleClicked(QListWidgetItem *)471 void MenuWidget::on_lwPlayersList_itemDoubleClicked(QListWidgetItem */*item*/)
472 {
473 on_bProfileSelect_clicked();
474 }
475
476 /*
477 void MenuWidget::on_bHallBack_clicked()
478 {
479 setCurrentIndex(MENU_MAIN);
480 }
481 */
482
on_bHelpBack_clicked()483 void MenuWidget::on_bHelpBack_clicked()
484 {
485 setCurrentIndex(MENU_MAIN);
486 }
487
on_bCreditsBack_clicked()488 void MenuWidget::on_bCreditsBack_clicked()
489 {
490 setCurrentIndex(MENU_MAIN);
491 }
492
on_bLevelsOk_clicked()493 void MenuWidget::on_bLevelsOk_clicked()
494 {
495 emit menuLevelPack();
496 }
497
on_bLevelsBack_clicked()498 void MenuWidget::on_bLevelsBack_clicked()
499 {
500 setCurrentIndex(MENU_OPTIONS);
501 }
502
on_lwLevels_itemDoubleClicked(QListWidgetItem *)503 void MenuWidget::on_lwLevels_itemDoubleClicked(QListWidgetItem */*item*/)
504 {
505 on_bLevelsOk_clicked();
506 }
507
on_bLangBack_clicked()508 void MenuWidget::on_bLangBack_clicked()
509 {
510 setCurrentIndex(MENU_OPTIONS);
511 }
512
on_bLangOk_clicked()513 void MenuWidget::on_bLangOk_clicked()
514 {
515 QString lang;
516 int row = ui.lwLanguage->currentRow();
517 if (row >= 0)
518 lang = ui.lwLanguage->item(row)->text();
519
520 QString langfile = GameWidget::getResourcePath() + "lang/langlist.dat";
521 QFile f(langfile);
522 if (!f.open(QFile::ReadOnly | QFile::Text))
523 return;
524 QTextStream ts(&f);
525
526 QSettings settings("xlabsoft","chains");
527 bool found = false;
528 while (!ts.atEnd()) {
529 QString qs = ts.readLine().simplified();
530 QString langname = qs.section("::",0,0).simplified();
531 QString langid = qs.section("::",1,1).simplified();
532 if (!langname.isEmpty() && langname == lang && !langid.isEmpty()) {
533 QString curlang = settings.value("Language", "").toString();
534 settings.setValue("Language", langid);
535 found = true;
536 break;
537 }
538 }
539 f.close();
540
541 if (!found || row == 0)
542 settings.setValue("Language", "");
543
544 if (found || row == 0)
545 QMessageBox::information(0, tr("Restart needed"),
546 tr("In order to change game language,\n please restart the game."),
547 QMessageBox::Close);
548 on_bLangBack_clicked();
549 }
550
on_lwLanguage_itemDoubleClicked(QListWidgetItem *)551 void MenuWidget::on_lwLanguage_itemDoubleClicked(QListWidgetItem */*item*/)
552 {
553 on_bLangOk_clicked();
554 }
555
556 ////////////////////////////////////////////////////////////////////////////////
on_menuNew()557 void GameScene::on_menuNew()
558 {
559 if (menu->isActive()) {
560 // ask confirmation
561 if (gameProfile->currentPlayer()->currentLevelPackInfo()->level > 1) {
562 //menu->hide();
563 if (!dconfirm->exec(tr("Current progress will be lost.\nAre you sure you want to start new game?")))
564 {
565 //menu->showNormal();
566 return;
567 }
568 }
569 //
570 // menu->setMenuPage(MENU_GAME);
571 // menu->activate();
572
573
574 // temp
575
576 on_menuGameStart();
577 }
578 }
579
on_menuContinue()580 void GameScene::on_menuContinue()
581 {
582 if (gameProfile->currentPlayer()->currentLevelPackInfo()->level > max_level) return;
583
584 menu->activate(false);
585 gameProfile->setGameStarted(true);
586 gameProfile->setGamePaused(false);
587 if (!initLevel(gameProfile->currentPlayer()->currentLevelPackInfo()->level))
588 exitToMainMenu();
589 }
590
on_menuExit()591 void GameScene::on_menuExit()
592 {
593 // ask confirmation
594 //menu->hide();
595 if (dconfirm->exec(tr("Are you sure you want to quit?"))) {
596 stopGame();
597 qApp->quit();
598 }
599 //menu->showNormal();
600 }
601
on_menuPauseBack()602 void GameScene::on_menuPauseBack()
603 {
604 menu->activate(false);
605 continueGame();
606 }
607
on_menuRestartLevel()608 void GameScene::on_menuRestartLevel()
609 {
610 //menu->hide();
611 if (dconfirm->exec(tr("Current level progress will be lost.\nAre you sure you want to restart?")))
612 {
613 if (!initLevel(gameProfile->currentPlayer()->currentLevelPackInfo()->level))
614 exitToMainMenu();
615 on_menuPauseBack();
616 return;
617 }
618 //menu->showNormal();
619 }
620
on_menuAbandonGame()621 void GameScene::on_menuAbandonGame()
622 {
623 //menu->hide();
624 if (dconfirm->exec(tr("Current level progress will be lost.\nAre you sure you want to quit?")))
625 {
626 // go to main menu
627 exitToMainMenu();
628 }
629 //menu->showNormal();
630 }
631
on_menuThemeChanged()632 void GameScene::on_menuThemeChanged()
633 {
634 myLock = true;
635 initTheme();
636 drawConcretesOnBackground();
637 drawHUDonBackground();
638 myLock = false;
639 }
640
on_menuGameStart()641 void GameScene::on_menuGameStart()
642 {
643 menu->activate(false);
644 gameProfile->setGameStarted(true);
645 gameProfile->setGamePaused(false);
646
647 LevelPackInfo *lpi = gameProfile->currentPlayer()->currentLevelPackInfo();
648 lpi->init();
649
650 // temp
651 lpi->diff = 2; // normal
652
653 if (!initLevel(1))
654 exitToMainMenu();
655 }
656
on_menuLevelPack()657 void GameScene::on_menuLevelPack()
658 {
659 // ask to change levelpack
660 menu->hide();
661 QString name = menu->selectedLevelPack();
662 if (gameProfile->currentLevelPack() != name) {
663 if (!dconfirm->exec(tr("Are you sure you want to select this level pack?"))) {
664 menu->showNormal();
665 return;
666 }
667 gameProfile->setCurrentLevelPack(name);
668 max_level = gameProfile->levelPackCount(gameProfile->currentLevelPack());
669 update();
670 }
671 menu->showNormal();
672 menu->setCurrentIndex(MENU_OPTIONS);
673 }
674
confirmExit()675 bool GameScene::confirmExit()
676 {
677 if (gameProfile->isGameStarted())
678 {
679 pauseGame();
680 }
681
682 // if (menu->isActive())
683 // menu->hide();
684
685 if (dconfirm->exec(tr("Any unsaved progress will be lost.\nAre you sure you want to quit?")))
686 return true;
687
688 // if (menu->isActive())
689 // menu->showNormal();
690
691 if (gameProfile->isGamePaused()) {
692 menu->activate(false);
693 continueGame();
694 }
695 return false;
696 }
697