1 /*
2     SPDX-FileCopyrightText: 2000 Roman Merzlyakov <roman@sbrf.barrt.ru>
3     SPDX-FileCopyrightText: 2000 Roman Razilov <roman@sbrf.barrt.ru>
4     SPDX-FileCopyrightText: 2007 Dimitry Suzdalev <dimsuz@gmail.com>
5     SPDX-FileCopyrightText: 2007 Simon Hürlimann <simon.huerlimann@huerlisi.ch>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #include "klines.h"
11 #include "renderer.h"
12 #include "prefs.h"
13 #include "mwidget.h"
14 #include "scene.h"
15 
16 #include <QStatusBar>
17 #include <QAction>
18 
19 #include <KConfig>
20 #include <KActionCollection>
21 #include <KStandardAction>
22 #include <KScoreDialog>
23 #include <KToggleAction>
24 #include <KConfigDialog>
25 #include <KMessageBox>
26 #include <KLocalizedString>
27 #include <KStandardGameAction>
28 #include <KGameRenderer>
29 #include <KgThemeSelector>
30 
KLinesMainWindow()31 KLinesMainWindow::KLinesMainWindow()
32 {
33     KLinesRenderer::Init();
34 
35     mwidget = new MainWidget(this);
36     setCentralWidget( mwidget );
37 
38     connect(mwidget->scene(), &KLinesScene::scoreChanged, this, &KLinesMainWindow::updateScore);
39     connect(mwidget->scene(), &KLinesScene::stateChanged, this,
40             qOverload<const QString &>(&KLinesMainWindow::slotStateChanged));
41     connect(mwidget->scene(), &KLinesScene::gameOver, this, &KLinesMainWindow::gameOver);
42 
43     scoreLabel->setText(i18n("Score:"));
44     statusBar()->addPermanentWidget(scoreLabel);
45 
46     updateScore(0);
47 
48     KgThemeProvider* prov = KLinesRenderer::renderer()->themeProvider();
49     connect(prov, &KgThemeProvider::currentThemeChanged, this, &KLinesMainWindow::loadSettings);
50     mselector = new KgThemeSelector(KLinesRenderer::renderer()->themeProvider());
51 
52     setupActions();
53 
54     stateChanged(QStringLiteral( "init" ));
55 }
56 
~KLinesMainWindow()57 KLinesMainWindow::~KLinesMainWindow()
58 {
59   KLinesRenderer::UnInit();
60 }
61 
setupActions()62 void KLinesMainWindow::setupActions()
63 {
64   // Game
65   KStandardGameAction::gameNew(this, &KLinesMainWindow::startGame, actionCollection());
66   KStandardGameAction::highscores(this, &KLinesMainWindow::viewHighScore, actionCollection());
67   KStandardGameAction::quit(this, &QWidget::close, actionCollection());
68   KStandardGameAction::end(mwidget->scene(), &KLinesScene::endGame, actionCollection());
69 
70   // Move
71   KStandardGameAction::undo(mwidget->scene(), &KLinesScene::undo, actionCollection());
72   KStandardGameAction::endTurn(mwidget->scene(), &KLinesScene::endTurn, actionCollection());
73 
74   // Preferences
75   KToggleAction *showNext = actionCollection()->add<KToggleAction>(QStringLiteral( "show_next" ));
76   showNext->setText( i18n( "Show Next" ) );
77   connect(showNext, &KToggleAction::triggered, this, &KLinesMainWindow::showNextToggled);
78 
79   showNext->setChecked(Prefs::showNext());
80   mwidget->setShowNextColors(Prefs::showNext());
81 
82   // Navigation
83   QAction* naviLeft = new QAction( i18n("Move Left" ), this );
84   naviLeft->setIcon(QIcon::fromTheme(QStringLiteral( "arrow-left")));
85   actionCollection()->setDefaultShortcut(naviLeft, Qt::Key_Left );
86   actionCollection()->addAction( QStringLiteral( "navi_left" ), naviLeft);
87 
88   QAction* naviRight = new QAction( i18n("Move Right" ), this );
89   naviRight->setIcon(QIcon::fromTheme(QStringLiteral( "arrow-right")));
90   actionCollection()->setDefaultShortcut(naviRight, Qt::Key_Right );
91   actionCollection()->addAction( QStringLiteral( "navi_right" ), naviRight);
92 
93   QAction* naviUp = new QAction( i18n("Move Up" ), this );
94   naviUp->setIcon(QIcon::fromTheme(QStringLiteral( "arrow-up")));
95   actionCollection()->setDefaultShortcut(naviUp, Qt::Key_Up );
96   actionCollection()->addAction( QStringLiteral( "navi_up" ), naviUp);
97 
98   QAction* naviDown = new QAction( i18n("Move Down" ), this );
99   naviDown->setIcon(QIcon::fromTheme(QStringLiteral( "arrow-down")));
100   actionCollection()->setDefaultShortcut(naviDown, Qt::Key_Down );
101   actionCollection()->addAction( QStringLiteral( "navi_down" ), naviDown);
102 
103   QAction* naviSelect = new QAction( i18n("Select"), this );
104   actionCollection()->setDefaultShortcut(naviSelect, Qt::Key_Space );
105   actionCollection()->addAction( QStringLiteral( "navi_select" ), naviSelect);
106 
107   connect( naviLeft, &QAction::triggered, mwidget->scene(), &KLinesScene::moveFocusLeft);
108   connect( naviRight, &QAction::triggered, mwidget->scene(), &KLinesScene::moveFocusRight);
109   connect( naviUp, &QAction::triggered, mwidget->scene(), &KLinesScene::moveFocusUp);
110   connect( naviDown, &QAction::triggered, mwidget->scene(), &KLinesScene::moveFocusDown);
111   connect( naviSelect, &QAction::triggered, mwidget->scene(), &KLinesScene::cellSelected);
112 
113   KStandardAction::preferences(mselector, [this]() { mselector->showAsDialog(); }, actionCollection());
114   setupGUI();
115 }
116 
updateScore(int score)117 void KLinesMainWindow::updateScore(int score)
118 {
119     scoreLabel->setText(i18n("Score: %1", score));
120 }
121 
gameOver(int score)122 void KLinesMainWindow::gameOver(int score)
123 {
124     KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
125     d.setConfigGroup(qMakePair(QByteArray("Highscore"), i18n("High Scores")));
126     d.addScore(score, KScoreDialog::AskName);
127     d.exec();
128 }
129 
viewHighScore()130 void KLinesMainWindow::viewHighScore()
131 {
132    KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
133    d.setConfigGroup(qMakePair(QByteArray("Highscore"), i18n("High Scores")));
134    d.exec();
135 }
136 
startGame()137 void KLinesMainWindow::startGame()
138 {
139     updateScore(0);
140     mwidget->scene()->startNewGame();
141 }
142 
showNextToggled(bool show)143 void KLinesMainWindow::showNextToggled(bool show)
144 {
145     mwidget->setShowNextColors(show);
146     Prefs::setShowNext(show);
147     Prefs::self()->save();
148 }
149 
150 
151 // FIXME these are strings from old tutorial
152 // leave them if I ever want to use them when I'll impelement tutorial mode
153 /**
154        msg = i18n("The goal of the game is to put\n"
155        msg = i18n("You can make horizontal, vertical\n"
156                   "and diagonal lines.");
157        msg = i18n("Each turn, three new balls are placed on the board.");
158        msg = i18n("Every turn, you can move one ball.");
159        msg = i18n("To move a ball, click on it with the mouse,\n"
160                   "then click where you want the ball to go.");
161        msg = i18n("You just moved the blue ball!");
162        msg = i18n("Balls can be moved to every position on the board,\n"
163                   "as long as there are no other balls in their way.");
164        msg = i18n("Now we only need one more blue ball.");
165        msg = i18n("It seems to be our lucky day!");
166        msg = i18n("Hurray! And away they go!\n"
167                   "Now lets try the green balls.");
168        msg = i18n("Now you try!\n"
169                   "Click on the green ball and move it to the others!");
170        msg = i18n("Almost, try again!");
171        msg = i18n("Very good!");
172        msg = i18n("Whenever you complete a line you get an extra turn.");
173        msg = i18n("This is the end of this tutorial.\n"
174                   "Feel free to finish the game!");
175                   */
176 
loadSettings()177 void KLinesMainWindow::loadSettings()
178 {
179     KLinesRenderer::loadTheme();
180     QRectF r = mwidget->scene()->sceneRect();
181     mwidget->scene()->invalidate( r, QGraphicsScene::BackgroundLayer ); // redraw background
182     mwidget->scene()->resizeScene( (int)r.width(), (int)r.height() ); // redraw scene
183 }
184 
185 
186