From 0ff4eec8a8f05c4ba9d5ac7c95fc95ace6f7a51c Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 5 May 2021 09:54:52 -0400 Subject: [PATCH] Solitaire: Convert Solitaire window to be created from GML No functionial change here, but this more easily allows for adding GUI elements to the Solitaire window. This nests the SolitaireWidget as a child of the main window's widget so that the SolitaireWidget does not color the entire window green when it paints its background. --- Userland/Games/Solitaire/CMakeLists.txt | 3 +++ Userland/Games/Solitaire/Game.cpp | 11 ++++++----- Userland/Games/Solitaire/Game.h | 5 +++-- Userland/Games/Solitaire/Solitaire.gml | 10 ++++++++++ Userland/Games/Solitaire/main.cpp | 16 +++++++++++----- 5 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 Userland/Games/Solitaire/Solitaire.gml diff --git a/Userland/Games/Solitaire/CMakeLists.txt b/Userland/Games/Solitaire/CMakeLists.txt index 09ef04f528..059356c3a9 100644 --- a/Userland/Games/Solitaire/CMakeLists.txt +++ b/Userland/Games/Solitaire/CMakeLists.txt @@ -1,8 +1,11 @@ +compile_gml(Solitaire.gml SolitaireGML.h solitaire_gml) + set(SOURCES Card.cpp CardStack.cpp Game.cpp main.cpp + SolitaireGML.h ) serenity_app(Solitaire ICON app-solitaire) diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index 0a22602087..66c6bcd538 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -8,17 +8,16 @@ #include #include +REGISTER_WIDGET(Solitaire, Game); + namespace Solitaire { static const Color s_background_color { Color::from_rgb(0x008000) }; static constexpr uint8_t new_game_animation_delay = 5; static constexpr int s_timer_interval_ms = 1000 / 60; -Game::Game(Function&& on_score_update) - : m_on_score_update(move(on_score_update)) +Game::Game() { - set_fill_with_background_color(false); - m_stacks[Stock] = CardStack({ 10, 10 }, CardStack::Type::Stock); m_stacks[Waste] = CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste); m_stacks[Foundation4] = CardStack({ Game::width - Card::width - 10, 10 }, CardStack::Type::Foundation); @@ -120,7 +119,9 @@ void Game::setup() void Game::update_score(int to_add) { m_score = max(static_cast(m_score) + to_add, 0); - m_on_score_update(m_score); + + if (on_score_update) + on_score_update(m_score); } void Game::keydown_event(GUI::KeyEvent& event) diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index 18e6d3d875..179a478db3 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -21,8 +21,10 @@ public: virtual ~Game() override; void setup(); + Function on_score_update; + private: - Game(Function&& on_score_update); + Game(); class Animation { public: @@ -119,7 +121,6 @@ private: uint8_t m_new_game_animation_delay { 0 }; uint32_t m_score { 0 }; - Function m_on_score_update; }; } diff --git a/Userland/Games/Solitaire/Solitaire.gml b/Userland/Games/Solitaire/Solitaire.gml new file mode 100644 index 0000000000..e588ef1d58 --- /dev/null +++ b/Userland/Games/Solitaire/Solitaire.gml @@ -0,0 +1,10 @@ +@GUI::Widget { + fill_with_background_color: false + + layout: @GUI::VerticalBoxLayout { + } + + @Solitaire::Game { + name: "game" + } +} diff --git a/Userland/Games/Solitaire/main.cpp b/Userland/Games/Solitaire/main.cpp index 0b8423f30a..d2c0935d1e 100644 --- a/Userland/Games/Solitaire/main.cpp +++ b/Userland/Games/Solitaire/main.cpp @@ -5,6 +5,7 @@ */ #include "Game.h" +#include #include #include #include @@ -39,15 +40,21 @@ int main(int argc, char** argv) window->set_resizable(false); window->resize(Solitaire::Game::width, Solitaire::Game::height); - auto widget = Solitaire::Game::construct([&](uint32_t score) { + auto& widget = window->set_main_widget(); + widget.load_from_gml(solitaire_gml); + + auto& game = *widget.find_descendant_of_type_named("game"); + game.set_focus(true); + + game.on_score_update = [&](uint32_t score) { window->set_title(String::formatted("Score: {} - Solitaire", score)); - }); + }; auto menubar = GUI::Menubar::construct(); auto& game_menu = menubar->add_menu("&Game"); game_menu.add_action(GUI::Action::create("&New Game", { Mod_None, Key_F2 }, [&](auto&) { - widget->setup(); + game.setup(); })); game_menu.add_separator(); game_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { app->quit(); })); @@ -56,10 +63,9 @@ int main(int argc, char** argv) help_menu.add_action(GUI::CommonActions::make_about_action("Solitaire", app_icon, window)); window->set_menubar(move(menubar)); - window->set_main_widget(widget); window->set_icon(app_icon.bitmap_for_size(16)); window->show(); - widget->setup(); + game.setup(); return app->exec(); }