diff --git a/Userland/Games/GameOfLife/BoardWidget.cpp b/Userland/Games/GameOfLife/BoardWidget.cpp index 07ad23d2a1..b3ff7997c4 100644 --- a/Userland/Games/GameOfLife/BoardWidget.cpp +++ b/Userland/Games/GameOfLife/BoardWidget.cpp @@ -38,6 +38,12 @@ BoardWidget::BoardWidget(size_t rows, size_t columns) void BoardWidget::run_generation() { m_board->run_generation(); + if (!m_board->is_stalled()) + m_ticks++; + + if (on_tick) + on_tick(m_ticks); + update(); if (m_board->is_stalled()) { if (on_stall) @@ -91,6 +97,8 @@ void BoardWidget::toggle_cell(size_t row, size_t column) if (m_running || !m_toggling_cells || (m_last_cell_toggled.row == row && m_last_cell_toggled.column == column)) return; + m_ticks = 0; + m_last_cell_toggled = { row, column }; m_board->toggle_cell(row, column); @@ -100,6 +108,18 @@ void BoardWidget::toggle_cell(size_t row, size_t column) update(); } +void BoardWidget::clear_cells() +{ + m_ticks = 0; + m_board->clear(); +} + +void BoardWidget::randomize_cells() +{ + m_ticks = 0; + m_board->randomize(); +} + int BoardWidget::get_cell_size() const { int width = rect().width() / m_board->columns(); diff --git a/Userland/Games/GameOfLife/BoardWidget.h b/Userland/Games/GameOfLife/BoardWidget.h index 1bc8b0006d..1b3d5431f9 100644 --- a/Userland/Games/GameOfLife/BoardWidget.h +++ b/Userland/Games/GameOfLife/BoardWidget.h @@ -36,8 +36,8 @@ public: } void toggle_cell(size_t row, size_t column); - void clear_cells() { m_board->clear(); } - void randomize_cells() { m_board->randomize(); } + void clear_cells(); + void randomize_cells(); int get_cell_size() const; Gfx::IntSize get_board_offset() const; @@ -64,6 +64,7 @@ public: int running_timer_interval() const { return m_running_timer_interval; } void set_running_timer_interval(int interval); + Function on_tick; Function on_running_state_change; Function on_stall; Function on_pattern_selection_state_change; @@ -87,6 +88,8 @@ private: int m_running_timer_interval { 500 }; int m_running_pattern_preview_timer_interval { 100 }; + u64 m_ticks { 0 }; + RefPtr m_context_menu; RefPtr m_timer; diff --git a/Userland/Games/GameOfLife/GameOfLife.gml b/Userland/Games/GameOfLife/GameOfLife.gml index 77f5c0c3f7..b94d815872 100644 --- a/Userland/Games/GameOfLife/GameOfLife.gml +++ b/Userland/Games/GameOfLife/GameOfLife.gml @@ -61,5 +61,6 @@ @GUI::Statusbar { name: "statusbar" + segment_count: 2 } } diff --git a/Userland/Games/GameOfLife/main.cpp b/Userland/Games/GameOfLife/main.cpp index fbb57b8612..b4895a06d5 100644 --- a/Userland/Games/GameOfLife/main.cpp +++ b/Userland/Games/GameOfLife/main.cpp @@ -66,13 +66,9 @@ ErrorOr serenity_main(Main::Arguments arguments) board_widget->set_min_size(board_columns, board_rows); auto& statusbar = *main_widget->find_descendant_of_type_named("statusbar"); - statusbar.set_text(click_tip); - GUI::Application::the()->on_action_enter = [&statusbar](GUI::Action& action) { - statusbar.set_override_text(action.status_tip()); - }; - GUI::Application::the()->on_action_leave = [&statusbar](GUI::Action&) { - statusbar.set_override_text({}); - }; + auto width = board_widget->font().width("Ticks: 000,000,000"sv) + board_widget->font().max_glyph_width(); + statusbar.segment(1).set_fixed_width(ceil(width)); + statusbar.segment(0).set_text(click_tip); auto& columns_spinbox = *main_widget->find_descendant_of_type_named("columns_spinbox"); auto& rows_spinbox = *main_widget->find_descendant_of_type_named("rows_spinbox"); @@ -81,7 +77,7 @@ ErrorOr serenity_main(Main::Arguments arguments) rows_spinbox.set_value(board_rows); auto size_changed_function = [&] { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text(click_tip); board_widget->resize_board(rows_spinbox.value(), columns_spinbox.value()); board_widget->update(); }; @@ -107,20 +103,22 @@ ErrorOr serenity_main(Main::Arguments arguments) main_toolbar.add_action(play_pause_action); auto run_one_generation_action = GUI::Action::create("Run &Next Generation", { Mod_Ctrl, Key_Equal }, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"sv)), [&](const GUI::Action&) { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text(click_tip); board_widget->run_generation(); }); main_toolbar.add_action(run_one_generation_action); auto clear_board_action = GUI::Action::create("&Clear board", { Mod_Ctrl, Key_N }, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/delete.png"sv)), [&](auto&) { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text(click_tip); + statusbar.segment(1).set_text({}); board_widget->clear_cells(); board_widget->update(); }); main_toolbar.add_action(clear_board_action); auto randomize_cells_action = GUI::Action::create("&Randomize board", { Mod_Ctrl, Key_R }, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/reload.png"sv)), [&](auto&) { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text(click_tip); + statusbar.segment(1).set_text({}); board_widget->randomize_cells(); board_widget->update(); }); @@ -151,14 +149,18 @@ ErrorOr serenity_main(Main::Arguments arguments) })); help_menu->add_action(GUI::CommonActions::make_about_action("Game of Life"_string, app_icon, window)); + board_widget->on_tick = [&](u64 ticks) { + statusbar.segment(1).set_text(String::formatted("Ticks: {:'}", ticks).release_value_but_fixme_should_propagate_errors()); + }; + board_widget->on_running_state_change = [&]() { if (board_widget->is_running()) { - statusbar.set_text("Running..."_string); + statusbar.segment(0).set_text("Running..."_string); play_pause_action->set_icon(paused_icon); play_pause_action->set_text("&Pause"); main_widget->set_override_cursor(Gfx::StandardCursor::None); } else { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text("Paused"_string); play_pause_action->set_icon(play_icon); play_pause_action->set_text("&Play"); main_widget->set_override_cursor(Gfx::StandardCursor::Drag); @@ -179,18 +181,19 @@ ErrorOr serenity_main(Main::Arguments arguments) board_widget->on_stall = [&] { play_pause_action->activate(); - statusbar.set_text("Stalled..."_string); + statusbar.segment(0).set_text("Stalled"_string); }; board_widget->on_cell_toggled = [&](auto, auto, auto) { - statusbar.set_text(click_tip); + statusbar.segment(0).set_text(click_tip); + statusbar.segment(1).set_text({}); }; board_widget->on_pattern_selection_state_change = [&] { rotate_pattern_action->set_enabled(board_widget->selected_pattern() != nullptr); }; - window->resize(500, 420); + window->resize(600, 500); window->show(); return app->exec();