diff --git a/Userland/Games/Minesweeper/CMakeLists.txt b/Userland/Games/Minesweeper/CMakeLists.txt index ac76c1bb5f..5c5e219068 100644 --- a/Userland/Games/Minesweeper/CMakeLists.txt +++ b/Userland/Games/Minesweeper/CMakeLists.txt @@ -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 diff --git a/Userland/Games/Minesweeper/CustomGameDialog.cpp b/Userland/Games/Minesweeper/CustomGameDialog.cpp index ce5194d767..fd52f43932 100644 --- a/Userland/Games/Minesweeper/CustomGameDialog.cpp +++ b/Userland/Games/Minesweeper/CustomGameDialog.cpp @@ -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"); diff --git a/Userland/Games/Minesweeper/Field.cpp b/Userland/Games/Minesweeper/Field.cpp index 46a5628e9b..01059d6958 100644 --- a/Userland/Games/Minesweeper/Field.cpp +++ b/Userland/Games/Minesweeper/Field.cpp @@ -7,6 +7,7 @@ #include "Field.h" #include +#include #include #include #include @@ -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) diff --git a/Userland/Games/Minesweeper/MinesweeperCustomGameWindow.gml b/Userland/Games/Minesweeper/MinesweeperCustomGameWindow.gml index 754060ae8e..9230be05f9 100644 --- a/Userland/Games/Minesweeper/MinesweeperCustomGameWindow.gml +++ b/Userland/Games/Minesweeper/MinesweeperCustomGameWindow.gml @@ -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 {} diff --git a/Userland/Games/Minesweeper/MinesweeperWindow.gml b/Userland/Games/Minesweeper/MinesweeperWindow.gml new file mode 100644 index 0000000000..b4ca40408e --- /dev/null +++ b/Userland/Games/Minesweeper/MinesweeperWindow.gml @@ -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 {} + } +} diff --git a/Userland/Games/Minesweeper/main.cpp b/Userland/Games/Minesweeper/main.cpp index 883271acc4..91d5a5fd59 100644 --- a/Userland/Games/Minesweeper/main.cpp +++ b/Userland/Games/Minesweeper/main.cpp @@ -7,6 +7,7 @@ #include "CustomGameDialog.h" #include "Field.h" #include +#include #include #include #include @@ -46,51 +47,18 @@ ErrorOr 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()); - (void)TRY(widget->try_set_layout()); - widget->layout()->set_spacing(0); - - auto top_line = TRY(widget->try_add(Gfx::Orientation::Horizontal)); - top_line->set_fixed_height(2); - - auto container = TRY(widget->try_add()); - container->set_fill_with_background_color(true); - container->set_fixed_height(36); - (void)TRY(container->try_set_layout()); - - container->layout()->add_spacer(); - - auto flag_image = TRY(container->try_add()); - 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()); - flag_label->set_autosize(true); - flag_label->set_text_alignment(Gfx::TextAlignment::CenterLeft); - - container->layout()->add_spacer(); - - auto face_button = TRY(container->try_add()); - 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()); - 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()); - 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("separator"); + auto& container = *widget->find_descendant_of_type_named("container"); + auto& flag_label = *widget->find_descendant_of_type_named("flag_label"); + auto& time_label = *widget->find_descendant_of_type_named("time_label"); + auto& face_button = *widget->find_descendant_of_type_named("face_button"); auto field = TRY(widget->try_add(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); }));