1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 09:57:36 +00:00

Minesweeper: Update GML and fix layout issues

Converts Minesweeper's main widget to GML, polishes the custom
game window, formats the clock as human readable digital time, and
defers invoking Field's callback until the main widget has finished
relayout. Fixes inability to downsize the main window when shrinking
field size.
This commit is contained in:
thankyouverycool 2022-08-04 10:16:26 -04:00 committed by Andreas Kling
parent 4d09b5c4ba
commit 517c03f920
6 changed files with 77 additions and 51 deletions

View file

@ -5,9 +5,11 @@ serenity_component(
)
compile_gml(MinesweeperCustomGameWindow.gml MinesweeperCustomGameWindowGML.h minesweeper_custom_game_window_gml)
compile_gml(MinesweeperWindow.gml MinesweeperWindowGML.h minesweeper_window_gml)
set(SOURCES
MinesweeperCustomGameWindowGML.h
MinesweeperWindowGML.h
CustomGameDialog.cpp
Field.cpp
main.cpp

View file

@ -42,8 +42,7 @@ void CustomGameDialog::set_max_mines()
CustomGameDialog::CustomGameDialog(Window* parent_window)
: Dialog(parent_window)
{
resize(305, 90);
center_on_screen();
resize(300, 82);
set_resizable(false);
set_title("Custom game");

View file

@ -7,6 +7,7 @@
#include "Field.h"
#include <AK/HashTable.h>
#include <AK/NumberFormat.h>
#include <AK/Queue.h>
#include <AK/Random.h>
#include <LibConfig/Client.h>
@ -115,7 +116,7 @@ Field::Field(GUI::Label& flag_label, GUI::Label& time_label, GUI::Button& face_b
m_timer = Core::Timer::create_repeating(
1000, [this] {
++m_time_elapsed;
m_time_label.set_text(String::number(m_time_elapsed));
m_time_label.set_text(human_readable_digital_time(m_time_elapsed));
},
this);
m_mine_bitmap = Gfx::Bitmap::try_load_from_file("/res/icons/minesweeper/mine.png"sv).release_value_but_fixme_should_propagate_errors();
@ -199,7 +200,7 @@ void Field::reset()
m_first_click = true;
set_updates_enabled(false);
m_time_elapsed = 0;
m_time_label.set_text("0");
m_time_label.set_text("00:00");
m_flags_left = m_mine_count;
m_flag_label.set_text(String::number(m_flags_left));
m_timer->stop();
@ -520,7 +521,9 @@ void Field::set_field_size(Difficulty difficulty, size_t rows, size_t columns, s
m_mine_count = mine_count;
set_fixed_size(frame_thickness() * 2 + m_columns * square_size(), frame_thickness() * 2 + m_rows * square_size());
reset();
m_on_size_changed(Gfx::IntSize(min_size()));
deferred_invoke([this] {
m_on_size_changed(Gfx::IntSize(min_size()));
});
}
void Field::set_single_chording(bool enabled)

View file

@ -2,13 +2,14 @@
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
margins: [4]
spacing: 6
}
@GUI::GroupBox {
title: "Field"
autosize: true
layout: @GUI::HorizontalBoxLayout {
margins: [16, 6, 6]
margins: [6]
}
@GUI::Label {
@ -23,7 +24,7 @@
fixed_width: 40
}
@GUI::VerticalSeparator {}
@GUI::Layout::Spacer {}
@GUI::Label {
text: "Rows: "
@ -37,7 +38,7 @@
fixed_width: 40
}
@GUI::VerticalSeparator {}
@GUI::Layout::Spacer {}
@GUI::Label {
text: "Mines: "
@ -53,8 +54,9 @@
}
@GUI::Widget {
max_height: 24
layout: @GUI::HorizontalBoxLayout {}
layout: @GUI::HorizontalBoxLayout {
spacing: 10
}
@GUI::Layout::Spacer {}

View file

@ -0,0 +1,52 @@
@GUI::Widget {
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
spacing: 0
}
@GUI::HorizontalSeparator {
name: "separator"
fixed_height: 2
}
@GUI::Widget {
name: "container"
fixed_height: 36
layout: @GUI::HorizontalBoxLayout {}
@GUI::Layout::Spacer {}
@GUI::ImageWidget {
name: "flag_image"
bitmap: "/res/icons/minesweeper/flag.png"
}
@GUI::Label {
name: "flag_label"
autosize: true
}
@GUI::Layout::Spacer {}
@GUI::Button {
name: "face_button"
fixed_size: [36, 36]
focus_policy: "TabFocus"
button_style: "Coolbar"
}
@GUI::Layout::Spacer {}
@GUI::ImageWidget {
name: "time_image"
bitmap: "/res/icons/minesweeper/timer.png"
}
@GUI::Label {
name: "time_label"
autosize: true
}
@GUI::Layout::Spacer {}
}
}

View file

@ -7,6 +7,7 @@
#include "CustomGameDialog.h"
#include "Field.h"
#include <AK/URL.h>
#include <Games/Minesweeper/MinesweeperWindowGML.h>
#include <LibConfig/Client.h>
#include <LibCore/System.h>
#include <LibDesktop/Launcher.h>
@ -46,51 +47,18 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto window = TRY(GUI::Window::try_create());
window->set_resizable(false);
window->set_title("Minesweeper");
window->resize(139, 175);
window->resize(139, 177);
auto widget = TRY(window->try_set_main_widget<GUI::Widget>());
(void)TRY(widget->try_set_layout<GUI::VerticalBoxLayout>());
widget->layout()->set_spacing(0);
auto top_line = TRY(widget->try_add<GUI::SeparatorWidget>(Gfx::Orientation::Horizontal));
top_line->set_fixed_height(2);
auto container = TRY(widget->try_add<GUI::Widget>());
container->set_fill_with_background_color(true);
container->set_fixed_height(36);
(void)TRY(container->try_set_layout<GUI::HorizontalBoxLayout>());
container->layout()->add_spacer();
auto flag_image = TRY(container->try_add<GUI::Label>());
flag_image->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/minesweeper/flag.png"sv).release_value_but_fixme_should_propagate_errors());
flag_image->set_fixed_width(16);
auto flag_label = TRY(container->try_add<GUI::Label>());
flag_label->set_autosize(true);
flag_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
container->layout()->add_spacer();
auto face_button = TRY(container->try_add<GUI::Button>());
face_button->set_focus_policy(GUI::FocusPolicy::TabFocus);
face_button->set_button_style(Gfx::ButtonStyle::Coolbar);
face_button->set_fixed_size(36, 36);
container->layout()->add_spacer();
auto time_image = TRY(container->try_add<GUI::Label>());
time_image->set_fixed_width(16);
time_image->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/minesweeper/timer.png"sv).release_value_but_fixme_should_propagate_errors());
auto time_label = TRY(container->try_add<GUI::Label>());
time_label->set_fixed_width(50);
time_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
container->layout()->add_spacer();
widget->load_from_gml(minesweeper_window_gml);
auto& separator = *widget->find_descendant_of_type_named<GUI::HorizontalSeparator>("separator");
auto& container = *widget->find_descendant_of_type_named<GUI::Widget>("container");
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 field = TRY(widget->try_add<Field>(flag_label, time_label, face_button, [&](auto size) {
size.set_height(size.height() + container->min_size().height().as_int());
size.set_height(size.height() + separator.height() + container.height());
window->resize(size);
}));