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