From 871f5ba431775798c0db8378dd66394ee343b045 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Wed, 13 Sep 2023 01:13:17 +0100 Subject: [PATCH] 2048: Disable the undo and redo actions when unavailable This change also ensures that the redo stack is cleared when a move is made, so that it isn't possible to redo a previous move after having made a new one. --- Userland/Games/2048/main.cpp | 49 +++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/Userland/Games/2048/main.cpp b/Userland/Games/2048/main.cpp index 3bdbe22a45..84c2e2eb1b 100644 --- a/Userland/Games/2048/main.cpp +++ b/Userland/Games/2048/main.cpp @@ -93,6 +93,31 @@ ErrorOr serenity_main(Main::Arguments arguments) Vector undo_stack; Vector redo_stack; + RefPtr undo_action; + RefPtr redo_action; + + undo_action = GUI::CommonActions::make_undo_action([&](auto& action) { + redo_stack.append(game); + redo_action->set_enabled(true); + game = undo_stack.take_last(); + if (undo_stack.is_empty()) + action.set_enabled(false); + + update(); + }); + undo_action->set_enabled(false); + + redo_action = GUI::CommonActions::make_redo_action([&](auto& action) { + undo_stack.append(game); + undo_action->set_enabled(true); + game = redo_stack.take_last(); + if (redo_stack.is_empty()) + action.set_enabled(false); + + update(); + }); + redo_action->set_enabled(false); + auto change_settings = [&] { auto size_dialog = GameSizeDialog::construct(window, board_size, target_tile, evil_ai); if (size_dialog->exec() != GUI::Dialog::ExecResult::OK) @@ -118,6 +143,8 @@ ErrorOr serenity_main(Main::Arguments arguments) // Do not leak game states between games. undo_stack.clear(); redo_stack.clear(); + undo_action->set_enabled(false); + redo_action->set_enabled(false); game = Game(board_size, target_tile, evil_ai); @@ -131,6 +158,11 @@ ErrorOr serenity_main(Main::Arguments arguments) board_view->on_move = [&](Game::Direction direction) { undo_stack.append(game); + undo_action->set_enabled(true); + + redo_stack.clear(); + redo_action->set_enabled(false); + auto outcome = game.attempt_move(direction); switch (outcome) { case Game::MoveOutcome::OK: @@ -171,21 +203,8 @@ ErrorOr serenity_main(Main::Arguments arguments) start_a_new_game(); })); - game_menu->add_action(GUI::CommonActions::make_undo_action([&](auto&) { - if (undo_stack.is_empty()) - return; - redo_stack.append(game); - game = undo_stack.take_last(); - update(); - })); - - game_menu->add_action(GUI::CommonActions::make_redo_action([&](auto&) { - if (redo_stack.is_empty()) - return; - undo_stack.append(game); - game = redo_stack.take_last(); - update(); - })); + game_menu->add_action(*undo_action); + game_menu->add_action(*redo_action); game_menu->add_separator(); game_menu->add_action(GUI::Action::create("&Settings", TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/settings.png"sv)), [&](auto&) {