/* * Copyright (c) 2021, Andres Crucitti * * SPDX-License-Identifier: BSD-2-Clause */ #include "BoardWidget.h" #include #include #include #include #include #include #include #include #include #include #include const char* click_tip = "Tip: click the board to toggle individual cells, or click+drag to toggle multiple cells"; int main(int argc, char** argv) { auto app = GUI::Application::construct(argc, argv); auto app_icon = GUI::Icon::default_icon("app-gameoflife"); auto window = GUI::Window::construct(); window->set_icon(app_icon.bitmap_for_size(16)); size_t board_columns = 35; size_t board_rows = 35; window->set_double_buffering_enabled(false); window->set_title("Game Of Life"); auto& main_widget = window->set_main_widget(); main_widget.load_from_gml(game_of_life_gml); main_widget.set_fill_with_background_color(true); auto& main_toolbar = *main_widget.find_descendant_of_type_named("toolbar"); main_toolbar.layout()->set_margins({ 6, 0, 6, 0 }); auto& board_widget_container = *main_widget.find_descendant_of_type_named("board_widget_container"); auto& board_layout = board_widget_container.set_layout(); board_layout.set_spacing(0); auto& board_widget = board_widget_container.add(board_rows, board_columns); board_widget.randomize_cells(); auto& statusbar = *main_widget.find_descendant_of_type_named("statusbar"); statusbar.set_text(click_tip); auto& columns_spinbox = *main_widget.find_descendant_of_type_named("columns_spinbox"); auto& rows_spinbox = *main_widget.find_descendant_of_type_named("rows_spinbox"); columns_spinbox.set_value(board_columns); rows_spinbox.set_value(board_rows); auto size_changed_function = [&] { statusbar.set_text(click_tip); board_widget.resize_board(rows_spinbox.value(), columns_spinbox.value()); board_widget.update(); }; rows_spinbox.on_change = [&](auto) { size_changed_function(); }; columns_spinbox.on_change = [&](auto) { size_changed_function(); }; auto& interval_spinbox = *main_widget.find_descendant_of_type_named("interval_spinbox"); interval_spinbox.on_change = [&](auto value) { board_widget.set_running_timer_interval(value); }; interval_spinbox.set_value(150); auto paused_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/pause.png"); auto play_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/play.png"); auto toggle_running_action = GUI::Action::create("&Toggle Running", { Mod_None, Key_Return }, *play_icon, [&](GUI::Action&) { board_widget.set_running(!board_widget.is_running()); }); toggle_running_action->set_checkable(true); main_toolbar.add_action(toggle_running_action); auto run_one_generation_action = GUI::Action::create("Run &Next Generation", { Mod_Ctrl, Key_Equal }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [&](const GUI::Action&) { statusbar.set_text(click_tip); board_widget.run_generation(); }); main_toolbar.add_action(run_one_generation_action); auto clear_board_action = GUI::Action::create("&Clear board", { Mod_Ctrl, Key_N }, Gfx::Bitmap::load_from_file("/res/icons/16x16/delete.png"), [&](auto&) { statusbar.set_text(click_tip); board_widget.clear_cells(); board_widget.update(); }); main_toolbar.add_action(clear_board_action); auto randomize_cells_action = GUI::Action::create("&Randomize board", { Mod_Ctrl, Key_R }, Gfx::Bitmap::load_from_file("/res/icons/16x16/reload.png"), [&](auto&) { statusbar.set_text(click_tip); board_widget.randomize_cells(); board_widget.update(); }); main_toolbar.add_action(randomize_cells_action); auto menubar = GUI::Menubar::construct(); auto& game_menu = menubar->add_menu("&Game"); game_menu.add_action(clear_board_action); game_menu.add_action(randomize_cells_action); game_menu.add_separator(); game_menu.add_action(toggle_running_action); game_menu.add_action(run_one_generation_action); game_menu.add_separator(); game_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { GUI::Application::the()->quit(); })); auto& help_menu = menubar->add_menu("&Help"); help_menu.add_action(GUI::CommonActions::make_about_action("Game Of Life", app_icon, window)); window->set_menubar(move(menubar)); board_widget.on_running_state_change = [&]() { if (board_widget.is_running()) { statusbar.set_text("Running..."); toggle_running_action->set_icon(paused_icon); main_widget.set_override_cursor(Gfx::StandardCursor::None); } else { statusbar.set_text(click_tip); toggle_running_action->set_icon(play_icon); main_widget.set_override_cursor(Gfx::StandardCursor::Drag); } interval_spinbox.set_value(board_widget.running_timer_interval()); rows_spinbox.set_enabled(!board_widget.is_running()); columns_spinbox.set_enabled(!board_widget.is_running()); interval_spinbox.set_enabled(!board_widget.is_running()); run_one_generation_action->set_enabled(!board_widget.is_running()); clear_board_action->set_enabled(!board_widget.is_running()); randomize_cells_action->set_enabled(!board_widget.is_running()); board_widget.update(); }; board_widget.on_stall = [&] { toggle_running_action->activate(); statusbar.set_text("Stalled..."); }; board_widget.on_cell_toggled = [&](auto, auto, auto) { statusbar.set_text(click_tip); }; window->resize(500, 420); window->show(); return app->exec(); }