Minesweeper: Port to GML compilation

This patch ports minesweeper to GML compilation,
and introduces a few changes made to associated files.
This commit is contained in:
tetektoza 2023-09-25 19:45:37 +02:00 committed by Tim Schumacher
parent 1c37385904
commit 4db9996cc0
Notes: sideshowbarker 2024-07-17 06:20:50 +09:00
8 changed files with 95 additions and 30 deletions

View File

@ -4,18 +4,15 @@ serenity_component(
TARGETS Minesweeper
)
stringify_gml(MinesweeperCustomGameWindow.gml MinesweeperCustomGameWindowGML.h minesweeper_custom_game_window_gml)
stringify_gml(MinesweeperWindow.gml MinesweeperWindowGML.h minesweeper_window_gml)
compile_gml(MainWidget.gml MainWidgetGML.cpp)
compile_gml(CustomGameWidget.gml CustomGameWidgetGML.cpp)
set(SOURCES
CustomGameDialog.cpp
CustomGameWidgetGML.cpp
Field.cpp
main.cpp
)
set(GENERATED_SOURCES
MinesweeperCustomGameWindowGML.h
MinesweeperWindowGML.h
MainWidgetGML.cpp
)
serenity_app(Minesweeper ICON app-minesweeper)

View File

@ -7,11 +7,26 @@
#include "CustomGameDialog.h"
#include "Field.h"
#include <Games/Minesweeper/MinesweeperCustomGameWindowGML.h>
namespace Minesweeper {
ErrorOr<NonnullRefPtr<CustomGameDialog>> CustomGameDialog::try_create(GUI::Window* parent)
{
auto settings_widget = TRY(CustomGameWidget::try_create());
auto settings_dialog = TRY(adopt_nonnull_ref_or_enomem(new (nothrow)
CustomGameDialog(move(settings_widget), move(parent))));
return settings_dialog;
}
GUI::Dialog::ExecResult CustomGameDialog::show(GUI::Window* parent_window, Field& field)
{
auto dialog = CustomGameDialog::construct(parent_window);
auto dialog_or_error = CustomGameDialog::try_create(parent_window);
if (dialog_or_error.is_error()) {
GUI::MessageBox::show(parent_window, "Couldn't load custom game dialog"sv, "Error while opening custom game dialog"sv, GUI::MessageBox::Type::Error);
return ExecResult::Aborted;
}
auto dialog = dialog_or_error.release_value();
if (parent_window) {
dialog->set_icon(parent_window->icon());
@ -38,21 +53,20 @@ void CustomGameDialog::set_max_mines()
m_mines_spinbox->set_max((m_rows_spinbox->value() * m_columns_spinbox->value()) - 9);
}
CustomGameDialog::CustomGameDialog(Window* parent_window)
CustomGameDialog::CustomGameDialog(NonnullRefPtr<CustomGameWidget> custom_game_widget, GUI::Window* parent_window)
: Dialog(parent_window)
{
resize(300, 82);
set_resizable(false);
set_title("Custom Game");
auto main_widget = set_main_widget<GUI::Widget>();
main_widget->load_from_gml(minesweeper_custom_game_window_gml).release_value_but_fixme_should_propagate_errors();
set_main_widget(custom_game_widget);
m_columns_spinbox = *main_widget->find_descendant_of_type_named<GUI::SpinBox>("columns_spinbox");
m_rows_spinbox = *main_widget->find_descendant_of_type_named<GUI::SpinBox>("rows_spinbox");
m_mines_spinbox = *main_widget->find_descendant_of_type_named<GUI::SpinBox>("mines_spinbox");
m_ok_button = *main_widget->find_descendant_of_type_named<GUI::Button>("ok_button");
m_cancel_button = *main_widget->find_descendant_of_type_named<GUI::Button>("cancel_button");
m_columns_spinbox = *custom_game_widget->find_descendant_of_type_named<GUI::SpinBox>("columns_spinbox");
m_rows_spinbox = *custom_game_widget->find_descendant_of_type_named<GUI::SpinBox>("rows_spinbox");
m_mines_spinbox = *custom_game_widget->find_descendant_of_type_named<GUI::SpinBox>("mines_spinbox");
m_ok_button = *custom_game_widget->find_descendant_of_type_named<GUI::Button>("ok_button");
m_cancel_button = *custom_game_widget->find_descendant_of_type_named<GUI::Button>("cancel_button");
m_columns_spinbox->on_change = [this](auto) {
set_max_mines();
@ -72,3 +86,5 @@ CustomGameDialog::CustomGameDialog(Window* parent_window)
set_max_mines();
}
}

View File

@ -7,20 +7,25 @@
#pragma once
#include "CustomGameWidget.h"
#include <LibGUI/Button.h>
#include <LibGUI/Dialog.h>
#include <LibGUI/MessageBox.h>
#include <LibGUI/SpinBox.h>
class Field;
namespace Minesweeper {
class CustomGameDialog : public GUI::Dialog {
C_OBJECT(CustomGameDialog);
C_OBJECT_ABSTRACT(CustomGameDialog);
public:
static ExecResult show(GUI::Window* parent_window, Field& field);
static ErrorOr<NonnullRefPtr<CustomGameDialog>> try_create(GUI::Window* parent);
private:
CustomGameDialog(GUI::Window* parent_window);
CustomGameDialog(NonnullRefPtr<CustomGameWidget> custom_game_widget, GUI::Window* parent_window);
virtual ~CustomGameDialog() override = default;
void set_max_mines();
@ -31,3 +36,5 @@ private:
RefPtr<GUI::SpinBox> m_rows_spinbox;
RefPtr<GUI::SpinBox> m_mines_spinbox;
};
}

View File

@ -1,4 +1,4 @@
@GUI::Widget {
@Minesweeper::CustomGameWidget {
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
margins: [4]
@ -7,7 +7,6 @@
@GUI::GroupBox {
title: "Field"
autosize: true
layout: @GUI::HorizontalBoxLayout {
margins: [6]
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023, the SerenityOS developers
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGUI/Widget.h>
namespace Minesweeper {
class CustomGameWidget : public GUI::Widget {
C_OBJECT_ABSTRACT(CustomGameWidget)
public:
static ErrorOr<NonnullRefPtr<CustomGameWidget>> try_create();
virtual ~CustomGameWidget() override = default;
private:
CustomGameWidget() = default;
};
}

View File

@ -1,4 +1,4 @@
@GUI::Widget {
@Minesweeper::MainWidget {
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
spacing: 0

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023, the SerenityOS developers
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGUI/Widget.h>
namespace Minesweeper {
class MainWidget : public GUI::Widget {
C_OBJECT_ABSTRACT(MainWidget)
public:
static ErrorOr<NonnullRefPtr<Minesweeper::MainWidget>> try_create();
virtual ~MainWidget() override = default;
private:
MainWidget() = default;
};
}

View File

@ -6,8 +6,8 @@
#include "CustomGameDialog.h"
#include "Field.h"
#include "MainWidget.h"
#include <AK/URL.h>
#include <Games/Minesweeper/MinesweeperWindowGML.h>
#include <LibConfig/Client.h>
#include <LibCore/System.h>
#include <LibDesktop/Launcher.h>
@ -49,14 +49,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
window->set_title("Minesweeper");
window->set_auto_shrink(true);
auto widget = window->set_main_widget<GUI::Widget>();
TRY(widget->load_from_gml(minesweeper_window_gml));
auto main_widget = TRY(Minesweeper::MainWidget::try_create());
window->set_main_widget(main_widget);
auto& flag_label = *widget->find_descendant_of_type_named<GUI::Label>("flag_label");
auto& time_label = *widget->find_descendant_of_type_named<GUI::Label>("time_label");
auto& face_button = *widget->find_descendant_of_type_named<GUI::Button>("face_button");
auto& flag_label = *main_widget->find_descendant_of_type_named<GUI::Label>("flag_label");
auto& time_label = *main_widget->find_descendant_of_type_named<GUI::Label>("time_label");
auto& face_button = *main_widget->find_descendant_of_type_named<GUI::Button>("face_button");
auto field = TRY(Field::create(flag_label, time_label, face_button));
TRY(widget->try_add_child(field));
TRY(main_widget->try_add_child(field));
auto game_menu = window->add_menu("&Game"_string);
@ -112,7 +112,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
difficulty_menu->add_separator();
action = GUI::Action::create_checkable("&Custom Game...", { Mod_Ctrl, Key_C }, [&](auto&) {
CustomGameDialog::show(window, field);
Minesweeper::CustomGameDialog::show(window, field);
});
action->set_checked(field->difficulty() == Field::Difficulty::Custom);
difficulty_menu->add_action(action);