|
|
@@ -3,7 +3,6 @@
|
|
|
#include "sigc++/adaptors/bind.h"
|
|
|
#include "sigc++/functors/mem_fun.h"
|
|
|
|
|
|
-
|
|
|
//}
|
|
|
// void MainWindow::ApplyStyles() {
|
|
|
// // Load and apply the CSS file
|
|
|
@@ -12,21 +11,25 @@
|
|
|
// Gtk::StyleContext::add_provider_for_display(Gdk::Display::get_default(), css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
|
|
// }
|
|
|
|
|
|
-void MainWindow::OnCellRightClick(int n_press, double n_x, double n_y, int index) {
|
|
|
+void MainWindow::OnCellRightClick(int n_press, double n_x, double n_y, int index)
|
|
|
+{
|
|
|
(void)n_press, (void)n_x, (void)n_y;
|
|
|
int x = index % field.getCols();
|
|
|
int y = index / field.getCols();
|
|
|
int pos = x + y * field.getRows();
|
|
|
|
|
|
- if(field.isOpened(x, y) == false) {
|
|
|
+ if (field.isOpened(x, y) == false)
|
|
|
+ {
|
|
|
field.toggleFlag(x, y);
|
|
|
- if(field.isFlagged(x, y)) {
|
|
|
+ if (field.isFlagged(x, y))
|
|
|
+ {
|
|
|
auto imgflag = Gtk::make_managed<Gtk::Image>();
|
|
|
imgflag->set(m_textureFlag);
|
|
|
buttons.at(pos)->set_child(*imgflag);
|
|
|
buttons.at(pos)->set_active(true);
|
|
|
}
|
|
|
- else {
|
|
|
+ else
|
|
|
+ {
|
|
|
buttons.at(pos)->unset_child();
|
|
|
buttons.at(pos)->queue_draw();
|
|
|
buttons.at(pos)->set_active(false);
|
|
|
@@ -34,7 +37,8 @@ void MainWindow::OnCellRightClick(int n_press, double n_x, double n_y, int index
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void MainWindow::updateFlagsLabel(int flags) {
|
|
|
+void MainWindow::updateFlagsLabel(int flags)
|
|
|
+{
|
|
|
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", flags);
|
|
|
flagLabel.set_label(msg);
|
|
|
}
|
|
|
@@ -57,78 +61,89 @@ void MainWindow::updateFlagsLabel(int flags) {
|
|
|
// clockConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::UpdateClockLabel), 100);
|
|
|
// }
|
|
|
|
|
|
+void MainWindow::OnCellClick(int x, int y)
|
|
|
+{
|
|
|
+ if (newGame)
|
|
|
+ {
|
|
|
+ field.initBombs(x, y);
|
|
|
+ newGame = false;
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-void MainWindow::OnCellClick(int x, int y) {
|
|
|
- if (newGame) {
|
|
|
- field.initBombs(x, y);
|
|
|
- newGame = false;
|
|
|
- }
|
|
|
-
|
|
|
- if(field.isFlagged(x, y)) {
|
|
|
- buttons.at(x + y * field.getRows())->set_active(true);
|
|
|
- }
|
|
|
- else {
|
|
|
- field.openCell(x, y);
|
|
|
- if(field.isBomb(x, y)) {
|
|
|
- openBombs();
|
|
|
- }
|
|
|
+ if (field.isFlagged(x, y))
|
|
|
+ {
|
|
|
+ buttons.at(x + y * field.getRows())->set_active(true);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ field.openCell(x, y);
|
|
|
+ if (field.isBomb(x, y))
|
|
|
+ {
|
|
|
+ openBombs();
|
|
|
}
|
|
|
-}
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-void MainWindow::openBombs() {
|
|
|
- for(int i=0; i < field.getCols() * field.getRows(); i++) {
|
|
|
+void MainWindow::openBombs()
|
|
|
+{
|
|
|
+ for (int i = 0; i < field.getCols() * field.getRows(); i++)
|
|
|
+ {
|
|
|
int x = i % field.getCols();
|
|
|
int y = i / field.getCols();
|
|
|
|
|
|
buttons.at(i)->set_sensitive(false);
|
|
|
|
|
|
- if(field.isBomb(x, y)) {
|
|
|
- if(field.isFlagged(x, y)) {
|
|
|
- auto imgFlagBomb = std::make_shared<Gtk::Image>();
|
|
|
- imgFlagBomb->set(m_textureFlagBomb);
|
|
|
- buttons.at(i)->set_child(*imgFlagBomb);
|
|
|
+ if (field.isBomb(x, y))
|
|
|
+ {
|
|
|
+ if (field.isFlagged(x, y))
|
|
|
+ {
|
|
|
+ auto imgFlagBomb = std::make_shared<Gtk::Image>();
|
|
|
+ imgFlagBomb->set(m_textureFlagBomb);
|
|
|
+ buttons.at(i)->set_child(*imgFlagBomb);
|
|
|
}
|
|
|
- else {
|
|
|
- auto imgBomb = std::make_shared<Gtk::Image>();
|
|
|
- imgBomb->set(m_textureBomb);
|
|
|
- buttons.at(i)->set_child(*imgBomb);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ auto imgBomb = std::make_shared<Gtk::Image>();
|
|
|
+ imgBomb->set(m_textureBomb);
|
|
|
+ buttons.at(i)->set_child(*imgBomb);
|
|
|
}
|
|
|
buttons.at(i)->set_active(true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void MainWindow::updateCell(int x, int y) {
|
|
|
+void MainWindow::updateCell(int x, int y)
|
|
|
+{
|
|
|
int pos = x + y * field.getRows();
|
|
|
- if(field.isOpened(x, y)) {
|
|
|
- if (field.bombsNearby(x, y) > 0) {
|
|
|
- switch(field.bombsNearby(x, y)) {
|
|
|
+ if (field.isOpened(x, y))
|
|
|
+ {
|
|
|
+ if (field.bombsNearby(x, y) > 0)
|
|
|
+ {
|
|
|
+ switch (field.bombsNearby(x, y))
|
|
|
+ {
|
|
|
case 1:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-1");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-1");
|
|
|
+ break;
|
|
|
case 2:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-2");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-2");
|
|
|
+ break;
|
|
|
case 3:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-3");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-3");
|
|
|
+ break;
|
|
|
case 4:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-4");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-4");
|
|
|
+ break;
|
|
|
case 5:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-5");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-5");
|
|
|
+ break;
|
|
|
case 6:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-6");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-6");
|
|
|
+ break;
|
|
|
case 7:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-7");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-7");
|
|
|
+ break;
|
|
|
case 8:
|
|
|
- buttons.at(pos)->get_style_context()->add_class("label-8");
|
|
|
- break;
|
|
|
+ buttons.at(pos)->get_style_context()->add_class("label-8");
|
|
|
+ break;
|
|
|
}
|
|
|
buttons.at(pos)->set_label(Glib::ustring::format(field.bombsNearby(x, y)));
|
|
|
}
|
|
|
@@ -150,7 +165,6 @@ void MainWindow::updateCell(int x, int y) {
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
-
|
|
|
// bool MainWindow::AllCellsOpened()
|
|
|
// {
|
|
|
// for(int i=0; i<COLS * COLS; i++) {
|
|
|
@@ -159,28 +173,30 @@ void MainWindow::updateCell(int x, int y) {
|
|
|
// }
|
|
|
// return true;
|
|
|
// }
|
|
|
-void MainWindow::gameOver() {
|
|
|
- //clockSignalConn.disconnect();
|
|
|
- //std::cout << "Signal gameOver emmited\n";
|
|
|
+void MainWindow::gameOver()
|
|
|
+{
|
|
|
+ // clockSignalConn.disconnect();
|
|
|
+ // std::cout << "Signal gameOver emmited\n";
|
|
|
}
|
|
|
|
|
|
void MainWindow::updateClockLabel()
|
|
|
{
|
|
|
|
|
|
- size_t time = field.getCurrentTime();
|
|
|
+ size_t time = 100; // field.getCurrentTime();
|
|
|
|
|
|
- int deciseconds = (time / 100) % 10;
|
|
|
+ int deciseconds = (time / 100) % 10;
|
|
|
int seconds = (time / 1000) % 60;
|
|
|
- int minutes = (time /60000) % 60;
|
|
|
-
|
|
|
- Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1:%2.%3", \
|
|
|
- Glib::ustring::format(std::setfill(L'0'), std::setw(2), minutes), \
|
|
|
- Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \
|
|
|
- Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds));
|
|
|
+ int minutes = (time / 60000) % 60;
|
|
|
+
|
|
|
+ Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1:%2.%3",
|
|
|
+ Glib::ustring::format(std::setfill(L'0'), std::setw(2), minutes),
|
|
|
+ Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds),
|
|
|
+ Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds));
|
|
|
clockLabel.set_label(msg);
|
|
|
}
|
|
|
|
|
|
-void MainWindow::handleClockSig(size_t time) {
|
|
|
+void MainWindow::handleClockSig(size_t time)
|
|
|
+{
|
|
|
(void)time;
|
|
|
m_clockDispatch.emit();
|
|
|
}
|
|
|
@@ -198,7 +214,7 @@ MainWindow::MainWindow()
|
|
|
boxH = Gtk::Box(Gtk::Orientation::HORIZONTAL);
|
|
|
|
|
|
boxH.set_hexpand(true);
|
|
|
-
|
|
|
+
|
|
|
boxV.append(boxH);
|
|
|
boxH.set_expand(true);
|
|
|
|
|
|
@@ -206,34 +222,33 @@ MainWindow::MainWindow()
|
|
|
labelMines.set_margin_top(12);
|
|
|
labelMines.set_margin_start(12);
|
|
|
labelMines.set_label(Glib::ustring::compose("Total mines: %1", field.getTotalMines()));
|
|
|
- //labelMines.set_hexpand(true);
|
|
|
-
|
|
|
+ // labelMines.set_hexpand(true);
|
|
|
+
|
|
|
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field.getRemainingFlags());
|
|
|
flagLabel = Gtk::Label(msg);
|
|
|
flagLabel.set_margin_top(12);
|
|
|
flagLabel.set_margin_start(12);
|
|
|
flagLabel.set_margin_end(12);
|
|
|
- //flagLabel.set_hexpand(true);
|
|
|
+ // flagLabel.set_hexpand(true);
|
|
|
|
|
|
clockLabel.set_margin_top(12);
|
|
|
- //clockLabel.set_margin_start(12);
|
|
|
- //Clocklabel.set_margin_end(12);
|
|
|
+ // clockLabel.set_margin_start(12);
|
|
|
+ // Clocklabel.set_margin_end(12);
|
|
|
clockLabel.set_hexpand(true);
|
|
|
Glib::ustring clockmsg = Glib::ustring::compose("Elapsed time: 00:00.0");
|
|
|
clockLabel.set_label(clockmsg);
|
|
|
-
|
|
|
+
|
|
|
boxH.append(labelMines);
|
|
|
boxH.append(clockLabel);
|
|
|
boxH.append(flagLabel);
|
|
|
|
|
|
-
|
|
|
- //TODO check if it's okay to mix std::shared_ptr with Gdk::ptr
|
|
|
+ // TODO check if it's okay to mix std::shared_ptr with Gdk::ptr
|
|
|
m_textureBomb = Gdk::Texture::create_from_resource("/minesweeper/bomb-solid");
|
|
|
m_textureFlag = Gdk::Texture::create_from_resource("/minesweeper/flag-solid");
|
|
|
m_textureFlagBomb = Gdk::Texture::create_from_resource("/minesweeper/flag-bomb");
|
|
|
|
|
|
// bombPix.set_from_resource("/minesweeper/bomb-solid");
|
|
|
-
|
|
|
+
|
|
|
auto css_provider = Gtk::CssProvider::create();
|
|
|
css_provider->load_from_data(
|
|
|
".label-1 { font-weight: bold; font-size: 1.5em; color: Blue; }\
|
|
|
@@ -244,11 +259,12 @@ MainWindow::MainWindow()
|
|
|
.label-6 { font-weight: bold; font-size: 1.5em; color: Salmon; }\
|
|
|
.label-7 { font-weight: bold; font-size: 1.5em; color: Turquoise; }\
|
|
|
.label-8 { font-weight: bold; font-size: 1.5em; color: Magenta; }");
|
|
|
-
|
|
|
+
|
|
|
auto display = Gdk::Display::get_default();
|
|
|
Gtk::StyleContext::add_provider_for_display(display, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
|
|
-
|
|
|
- for (int i = 0; i < field.getCols() * field.getRows(); i++) {
|
|
|
+
|
|
|
+ for (int i = 0; i < field.getCols() * field.getRows(); i++)
|
|
|
+ {
|
|
|
auto button = std::make_shared<Gtk::ToggleButton>();
|
|
|
button->set_size_request(50, 40);
|
|
|
button->set_sensitive(true);
|
|
|
@@ -257,55 +273,57 @@ MainWindow::MainWindow()
|
|
|
int y = i / field.getRows();
|
|
|
button->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::OnCellClick), x, y));
|
|
|
|
|
|
- //button->get_style_context()->add_class("fixed-button");
|
|
|
+ // button->get_style_context()->add_class("fixed-button");
|
|
|
|
|
|
auto gesture = Gtk::GestureClick::create();
|
|
|
gesture->set_button(3);
|
|
|
- gesture->signal_released().connect(sigc::bind(sigc::mem_fun(*this, \
|
|
|
- &MainWindow::OnCellRightClick), i));
|
|
|
+ gesture->signal_released().connect(sigc::bind(sigc::mem_fun(*this,
|
|
|
+ &MainWindow::OnCellRightClick),
|
|
|
+ i));
|
|
|
button->add_controller(gesture);
|
|
|
|
|
|
buttons.push_back(button);
|
|
|
-
|
|
|
+
|
|
|
grid.attach(*button, x, y);
|
|
|
}
|
|
|
|
|
|
field.openCellSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateCell)));
|
|
|
field.remainingFlagsSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateFlagsLabel)));
|
|
|
field.gameOverSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::gameOver)));
|
|
|
- //newGameButton.set_label("New");
|
|
|
- //newGameButton.add_css_class("suggested-action");
|
|
|
- //newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
|
|
+ // newGameButton.set_label("New");
|
|
|
+ // newGameButton.add_css_class("suggested-action");
|
|
|
+ // newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
|
|
|
|
|
- //optionButton.set_icon_name("open-menu");
|
|
|
+ // optionButton.set_icon_name("open-menu");
|
|
|
|
|
|
- field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::handleClockSig)));
|
|
|
+ // field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::handleClockSig)));
|
|
|
m_clockDispatch.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel)));
|
|
|
- //field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel)));
|
|
|
- //if (clockSignalConn.connected()) clockSignalConn.disconnect();
|
|
|
- //elapsedTime = 0;
|
|
|
- //clockSignalConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::updateClockLabel), 100);
|
|
|
- //}
|
|
|
- //create the minefield
|
|
|
- //field = new MineField(COLS, MINES);
|
|
|
-
|
|
|
- //bar.pack_start(newGameButton);
|
|
|
- //bar.pack_end(optionButton);
|
|
|
-
|
|
|
- //grid.set_row_homogeneous(false);
|
|
|
- //grid.set_column_homogeneous(false);
|
|
|
+ // field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel)));
|
|
|
+ // if (clockSignalConn.connected()) clockSignalConn.disconnect();
|
|
|
+ // elapsedTime = 0;
|
|
|
+ // clockSignalConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::updateClockLabel), 100);
|
|
|
+ // }
|
|
|
+ // create the minefield
|
|
|
+ // field = new MineField(COLS, MINES);
|
|
|
+
|
|
|
+ // bar.pack_start(newGameButton);
|
|
|
+ // bar.pack_end(optionButton);
|
|
|
+
|
|
|
+ // grid.set_row_homogeneous(false);
|
|
|
+ // grid.set_column_homogeneous(false);
|
|
|
grid.set_margin(10);
|
|
|
- //grid.set_vexpand(true);
|
|
|
- //grid.set_hexpand(true);
|
|
|
- // grid.set_fill(false);
|
|
|
+ // grid.set_vexpand(true);
|
|
|
+ // grid.set_hexpand(true);
|
|
|
+ // grid.set_fill(false);
|
|
|
|
|
|
boxV.append(grid);
|
|
|
-
|
|
|
+
|
|
|
this->set_titlebar(bar);
|
|
|
this->set_child(boxV);
|
|
|
}
|
|
|
|
|
|
-int main(int argc, char **argv) {
|
|
|
- auto app = Gtk::Application::create("eu.minesweeper");
|
|
|
+int main(int argc, char **argv)
|
|
|
+{
|
|
|
+ auto app = Gtk::Application::create("eu.bernardomagri.minesweeper");
|
|
|
return app->make_window_and_run<MainWindow>(argc, argv);
|
|
|
}
|