mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:17:44 +00:00
GameOfLife: Add a tick counter to the status bar
The counter is incremented after each new generation and reset whenever any cell on the board is toggled. Resizing the board does not reset the tick count.
This commit is contained in:
parent
7e9ea964a8
commit
19dfdeeaec
4 changed files with 45 additions and 18 deletions
|
@ -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();
|
||||
|
|
|
@ -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<void(u64)> on_tick;
|
||||
Function<void()> on_running_state_change;
|
||||
Function<void()> on_stall;
|
||||
Function<void()> 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<GUI::Menu> m_context_menu;
|
||||
|
||||
RefPtr<Core::Timer> m_timer;
|
||||
|
|
|
@ -61,5 +61,6 @@
|
|||
|
||||
@GUI::Statusbar {
|
||||
name: "statusbar"
|
||||
segment_count: 2
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,13 +66,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
board_widget->set_min_size(board_columns, board_rows);
|
||||
|
||||
auto& statusbar = *main_widget->find_descendant_of_type_named<GUI::Statusbar>("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<GUI::SpinBox>("columns_spinbox");
|
||||
auto& rows_spinbox = *main_widget->find_descendant_of_type_named<GUI::SpinBox>("rows_spinbox");
|
||||
|
@ -81,7 +77,7 @@ ErrorOr<int> 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<int> 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<int> 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<int> 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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue