main.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (c) 2022, Joe Petrus <joe@petrus.io>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "WordGame.h"
  7. #include <AK/URL.h>
  8. #include <LibConfig/Client.h>
  9. #include <LibCore/System.h>
  10. #include <LibDesktop/Launcher.h>
  11. #include <LibGUI/Action.h>
  12. #include <LibGUI/ActionGroup.h>
  13. #include <LibGUI/Application.h>
  14. #include <LibGUI/Icon.h>
  15. #include <LibGUI/InputBox.h>
  16. #include <LibGUI/Menubar.h>
  17. #include <LibGUI/MessageBox.h>
  18. #include <LibGUI/Window.h>
  19. #include <LibMain/Main.h>
  20. ErrorOr<int> serenity_main(Main::Arguments arguments)
  21. {
  22. TRY(Core::System::pledge("stdio rpath recvfd sendfd unix"));
  23. auto app = TRY(GUI::Application::try_create(arguments));
  24. Config::pledge_domain("MasterWord");
  25. TRY(Desktop::Launcher::add_allowed_handler_with_only_specific_urls("/bin/Help", { URL::create_with_file_protocol("/usr/share/man/man6/MasterWord.md") }));
  26. TRY(Desktop::Launcher::seal_allowlist());
  27. TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
  28. TRY(Core::System::unveil("/res", "r"));
  29. TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
  30. TRY(Core::System::unveil(nullptr, nullptr));
  31. auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-masterword"));
  32. auto window = TRY(GUI::Window::try_create());
  33. window->set_double_buffering_enabled(false);
  34. window->set_title("MasterWord");
  35. window->set_resizable(false);
  36. auto game = TRY(window->try_set_main_widget<WordGame>());
  37. auto use_system_theme = Config::read_bool("MasterWord", "", "use_system_theme", false);
  38. game->set_use_system_theme(use_system_theme);
  39. auto shortest_word = game->shortest_word();
  40. auto longest_word = game->longest_word();
  41. window->resize(game->game_size());
  42. auto game_menu = TRY(window->try_add_menu("&Game"));
  43. TRY(game_menu->try_add_action(GUI::Action::create("&New Game", { Mod_None, Key_F2 }, [&](auto&) {
  44. game->reset();
  45. })));
  46. TRY(game_menu->try_add_action(GUI::Action::create("Set &Word Length", [&](auto&) {
  47. auto word_length = Config::read_i32("MasterWord", "", "word_length", 5);
  48. auto word_length_string = String::number(word_length);
  49. if (GUI::InputBox::show(window, word_length_string, "Word length:", "MasterWord") == GUI::InputBox::ExecResult::OK && !word_length_string.is_empty()) {
  50. auto maybe_word_length = word_length_string.template to_uint();
  51. if (!maybe_word_length.has_value() || maybe_word_length.value() < shortest_word || maybe_word_length.value() > longest_word) {
  52. GUI::MessageBox::show(window, String::formatted("Please enter a number between {} and {}.", shortest_word, longest_word), "MasterWord");
  53. return;
  54. }
  55. word_length = maybe_word_length.value();
  56. Config::write_i32("MasterWord", "", "word_length", word_length);
  57. game->set_word_length(word_length);
  58. window->resize(game->game_size());
  59. }
  60. })));
  61. TRY(game_menu->try_add_action(GUI::Action::create("Set &Number Of Guesses", [&](auto&) {
  62. auto max_guesses = Config::read_i32("MasterWord", "", "max_guesses", 5);
  63. auto max_guesses_string = String::number(max_guesses);
  64. if (GUI::InputBox::show(window, max_guesses_string, "Maximum number of guesses:", "MasterWord") == GUI::InputBox::ExecResult::OK && !max_guesses_string.is_empty()) {
  65. auto maybe_max_guesses = max_guesses_string.template to_uint();
  66. if (!maybe_max_guesses.has_value() || maybe_max_guesses.value() < 1 || maybe_max_guesses.value() > 20) {
  67. GUI::MessageBox::show(window, "Please enter a number between 1 and 20.", "MasterWord");
  68. return;
  69. }
  70. max_guesses = maybe_max_guesses.value();
  71. Config::write_i32("MasterWord", "", "max_guesses", max_guesses);
  72. game->set_max_guesses(max_guesses);
  73. window->resize(game->game_size());
  74. }
  75. })));
  76. TRY(game_menu->try_add_separator());
  77. TRY(game_menu->try_add_action(GUI::CommonActions::make_quit_action([](auto&) {
  78. GUI::Application::the()->quit();
  79. })));
  80. auto theme_menu = TRY(window->try_add_menu("&Theme"));
  81. auto system_theme_action = GUI::Action::create("&System", [&](auto&) {
  82. game->set_use_system_theme(true);
  83. Config::write_bool("MasterWord", "", "use_system_theme", true);
  84. });
  85. system_theme_action->set_checkable(true);
  86. system_theme_action->set_checked(use_system_theme);
  87. TRY(theme_menu->try_add_action(system_theme_action));
  88. auto wordle_theme_action = GUI::Action::create("&Wordle", [&](auto&) {
  89. game->set_use_system_theme(false);
  90. Config::write_bool("MasterWord", "", "use_system_theme", false);
  91. });
  92. wordle_theme_action->set_checkable(true);
  93. wordle_theme_action->set_checked(!use_system_theme);
  94. TRY(theme_menu->try_add_action(wordle_theme_action));
  95. GUI::ActionGroup theme_actions;
  96. theme_actions.set_exclusive(true);
  97. theme_actions.set_unchecking_allowed(false);
  98. theme_actions.add_action(system_theme_action);
  99. theme_actions.add_action(wordle_theme_action);
  100. auto help_menu = TRY(window->try_add_menu("&Help"));
  101. TRY(help_menu->try_add_action(GUI::CommonActions::make_help_action([](auto&) {
  102. Desktop::Launcher::open(URL::create_with_file_protocol("/usr/share/man/man6/MasterWord.md"), "/bin/Help");
  103. })));
  104. TRY(help_menu->try_add_action(GUI::CommonActions::make_about_action("MasterWord", app_icon, window)));
  105. window->show();
  106. window->set_icon(app_icon.bitmap_for_size(16));
  107. return app->exec();
  108. }