41 std::vector<vertex_geometry::Rectangle> settings_menu = weighted_subdivision(settings_menu_rect, {1, 3},
true);
52 std::function<void()> on_hover = [&]() { sound_system.queue_sound(SoundType::UI_HOVER); };
53 std::function<void(
const std::string)> dropdown_on_hover = [&](
const std::string) {
54 sound_system.queue_sound(SoundType::UI_HOVER);
90 : window(window), input_state(input_state), batcher(batcher), sound_system(sound_system),
96 configuration.register_config_handler(
"graphics",
"resolution",
97 [&](
const std::string resolution) { window.set_resolution(resolution); });
99 configuration.register_config_handler(
"graphics",
"fullscreen",
100 [&](
const std::string value) { window.set_fullscreen_by_on_off(value); });
102 configuration.register_config_handler(
"graphics",
"wireframe", [&](
const std::string value) {
104 window.enable_wireframe_mode();
105 }
else if (value ==
"off") {
106 window.disable_wireframe_mode();
110 configuration.apply_config_logic();
112 logger.info(
"successfully initialized");
125 std::vector<UIState> get_ui_dependencies(
const UIState &ui_state) {
158 glm::vec2 get_ndc_mouse_pos(GLFWwindow *window,
double xpos,
double ypos) {
160 glfwGetWindowSize(window, &width, &height);
162 return {(2.0f * xpos) / width - 1.0f, 1.0f - (2.0f * ypos) / height};
172 glm::vec2 aspect_corrected_ndc_mouse_pos(
const glm::vec2 &ndc_mouse_pos,
float x_scale) {
173 return {ndc_mouse_pos.x * x_scale, ndc_mouse_pos.y};
191 get_ndc_mouse_pos(window.glfw_window, input_state.mouse_position_x, input_state.mouse_position_y);
192 auto acnmp = aspect_corrected_ndc_mouse_pos(ndc_mouse_pos, window.width_px / (
float)window.height_px);
194 std::vector<UIState> uis_to_render = {
curr_state};
195 for (
const auto &ui_state : get_ui_dependencies(
curr_state)) {
196 uis_to_render.push_back(ui_state);
199 for (
const auto &ui_state : uis_to_render) {
204 acnmp, selected_ui, ui_render_suite, input_state.get_keys_just_pressed_this_tick(),
220 UI create_main_menu_ui() {
222 std::function<void()> on_program_start = [&]() {
223 sound_system.queue_sound(SoundType::UI_CLICK);
226 std::function<void()> on_click_settings = [&]() {
227 sound_system.queue_sound(SoundType::UI_CLICK);
230 std::function<void()> on_click_about = [&]() {
231 sound_system.queue_sound(SoundType::UI_CLICK);
234 std::function<void()> on_game_quit = [&]() {
235 sound_system.queue_sound(SoundType::UI_CLICK);
236 glfwSetWindowShouldClose(window.glfw_window, GLFW_TRUE);
238 std::function<void()> on_back_clicked = [&]() {
239 sound_system.queue_sound(SoundType::UI_CLICK);
246 UI
main_menu_ui(0, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
249 vertex_geometry::Grid grid(4, 1, 0.5, 0.5);
250 auto frag_time_rect = grid.get_at(0, 0);
254 auto settings_rect = grid.get_at(0, 1);
258 auto credits_rect = grid.get_at(0, 2);
262 auto exit_rect = grid.get_at(0, 3);
276 UI create_about_ui() {
279 UI
about_ui(0, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
280 std::function<void(std::string)> on_confirm = [&](std::string contents) { std::cout << contents << std::endl; };
284 "this program was created with the toolbox engine, this engine is an open source collection of tools "
285 "which come together to form an engine to make games using c++, it's designed for programmers and just "
286 "gives you tools to do stuff faster in that realm instead of an all encompassing solution. Learn more "
287 "about it at cpptbx.cuppajoeman.com and join the discord."),
290 about_ui.add_clickable_textbox(on_back_clicked, on_hover,
"back to main menu", -0.65, -0.65, 0.5, 0.5,
306 UI create_settings_menu_ui() {
307 UI
settings_menu_ui(0, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
309 vertex_geometry::Grid top_row_grid(1, 5, settings_menu.at(0));
311 std::function<void()> on_back_clicked = [&]() {
312 sound_system.queue_sound(SoundType::UI_CLICK);
315 std::function<void()> on_apply_clicked = [&]() {
316 sound_system.queue_sound(SoundType::UI_CLICK);
317 configuration.apply_config_logic();
319 std::function<void()> on_save_clicked = [&]() {
320 sound_system.queue_sound(SoundType::UI_CLICK);
321 configuration.save_to_file();
323 std::function<void()> settings_on_click = [&]() { sound_system.queue_sound(SoundType::UI_CLICK); };
325 std::function<void()> player_on_click = [&]() {
326 sound_system.queue_sound(SoundType::UI_CLICK);
329 auto player_rect = top_row_grid.get_at(0, 0);
333 std::function<void()> input_on_click = [&]() {
334 sound_system.queue_sound(SoundType::UI_CLICK);
337 auto input_rect = top_row_grid.get_at(1, 0);
341 std::function<void()> sound_on_click = [&]() {
342 sound_system.queue_sound(SoundType::UI_CLICK);
345 auto sound_rect = top_row_grid.get_at(2, 0);
349 std::function<void()> graphics_on_click = [&]() {
350 sound_system.queue_sound(SoundType::UI_CLICK);
353 auto graphics_rect = top_row_grid.get_at(3, 0);
357 std::function<void()> network_on_click = [&]() {
358 sound_system.queue_sound(SoundType::UI_CLICK);
361 auto network_rect = top_row_grid.get_at(4, 0);
365 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
369 glm::vec3(-1, -0.75, 0), glm::vec3(-0.75, -0.75, 0), glm::vec3(-1, -1, 0), glm::vec3(-0.75, -1, 0));
374 glm::vec3(1, -0.75, 0), glm::vec3(0.75, -0.75, 0), glm::vec3(1, -1, 0), glm::vec3(0.75, -1, 0));
383 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
396 UI create_player_settings_ui() {
398 std::function<void(std::string)> on_confirm = [&](std::string contents) { std::cout << contents << std::endl; };
400 UI
player_settings_ui(-0.1, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
402 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
403 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
405 std::function<void(std::string)> username_on_confirm = [](std::string
s) {};
411 vertex_geometry::Grid input_settings_grid(10, 3, main_settings_rect);
426 UI create_input_settings_ui() {
428 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
429 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
431 vertex_geometry::Grid input_settings_grid(11, 3, main_settings_rect);
432 UI
input_settings_ui(-0.1, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
435 std::function<void(std::string)> sens_on_click = [
this](std::string option) {
436 sound_system.queue_sound(SoundType::UI_CLICK);
437 configuration.set_value(
"input",
"mouse_sensitivity", option);
443 std::function<void(std::string)> on_confirm = [&](std::string contents) { std::cout << contents << std::endl; };
453 std::function<std::function<void(std::string)>(std::string)> create_key_on_confirm_function =
454 [&](std::string key_str) {
455 return [
this, key_str](std::string input_value) {
456 if (input_state.is_valid_key_string(input_value)) {
457 configuration.set_value(
"input", key_str, input_value);
458 sound_system.queue_sound(SoundType::UI_CLICK);
460 logger.warn(
"{} is not a valid key string, not setting it in the config, use a proper value.",
468 configuration.get_value(
"input",
"forward").value_or(
"w"),
472 input_settings_ui.add_input_box(create_key_on_confirm_function(
"back"),
"s", input_settings_grid.get_at(2, 4),
476 input_settings_ui.add_input_box(create_key_on_confirm_function(
"left"),
"a", input_settings_grid.get_at(2, 5),
480 input_settings_ui.add_input_box(create_key_on_confirm_function(
"right"),
"d", input_settings_grid.get_at(2, 6),
484 input_settings_ui.add_input_box(create_key_on_confirm_function(
"left"),
" ", input_settings_grid.get_at(2, 7),
488 input_settings_ui.add_input_box(create_key_on_confirm_function(
"down"),
"left_shift",
492 input_settings_ui.add_input_box(create_key_on_confirm_function(
"slow_move"),
"left_control",
496 input_settings_ui.add_input_box(create_key_on_confirm_function(
"fast_move"),
"tab",
510 UI create_sound_settings_ui() {
512 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
513 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
515 vertex_geometry::Grid sound_settings_grid(1, 3, main_settings_rect);
516 UI
sound_settings_ui(-0.1, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
521 int get_index_or_default(
const std::string &value,
const std::vector<std::string> &vec) {
522 auto it = std::find(vec.begin(), vec.end(), value);
523 return (it != vec.end()) ? std::distance(vec.begin(), it) : 0;
537 UI create_graphics_settings_ui() {
541 if (resolutions.empty())
542 resolutions = {
"1920x1080"};
544 std::function<void(std::string)> on_confirm = [&](std::string contents) { std::cout << contents << std::endl; };
546 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
547 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
553 vertex_geometry::Grid graphics_settings_grid(10, 3, main_settings_rect);
554 UI
graphics_settings_ui(-0.1, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
556 std::vector<std::string> options = resolutions;
557 std::vector<std::function<void()>> option_on_clicks(options.size(), []() {});
559 std::function<void(std::string)> empty_on_click = [](std::string option) { std::cout << option << std::endl; };
561 std::function<void(std::string)> resolution_dropdown_on_click = [
this](std::string option) {
562 sound_system.queue_sound(SoundType::UI_CLICK);
563 size_t x_pos = option.find(
'x');
564 unsigned int width, height;
565 if (x_pos != std::string::npos) {
566 width = std::stoi(option.substr(0, x_pos));
567 height = std::stoi(option.substr(x_pos + 1));
570 configuration.set_value(
"graphics",
"resolution", option);
572 throw std::invalid_argument(
"Input string is not in the correct format (e.g. 1280x960)");
576 int dropdown_option_idx;
578 dropdown_option_idx =
579 get_index_or_default(configuration.get_value(
"graphics",
"resolution").value_or(
"1280x720"), options);
584 options, resolution_dropdown_on_click, dropdown_on_hover);
586 std::function<void(std::string)> fullscreen_on_click = [
this](std::string option) {
587 sound_system.queue_sound(SoundType::UI_CLICK);
588 configuration.set_value(
"graphics",
"fullscreen", option);
591 dropdown_option_idx =
592 get_index_or_default(configuration.get_value(
"graphics",
"fullscreen").value_or(
"off"), on_off_options);
596 on_off_options, fullscreen_on_click, dropdown_on_hover);
598 std::function<void(std::string)> wireframe_on_click = [
this](std::string option) {
599 sound_system.queue_sound(SoundType::UI_CLICK);
600 configuration.set_value(
"graphics",
"wireframe", option);
603 dropdown_option_idx =
604 get_index_or_default(configuration.get_value(
"graphics",
"wireframe").value_or(
"off"), on_off_options);
608 on_off_options, wireframe_on_click, dropdown_on_hover);
610 std::function<void(std::string)> fov_on_confirm = [&](std::string option) {
611 configuration.set_value(
"graphics",
"field_of_view", option);
616 fov_on_confirm, configuration.get_value(
"graphics",
"field_of_view").value_or(
"degrees (30-160 limit)"),
619 std::function<void(std::string)> max_fps_on_confirm = [&](std::string option) {
620 configuration.set_value(
"graphics",
"max_fps", option);
625 configuration.get_value(
"graphics",
"max_fps").value_or(
"120"),
628 std::function<void(std::string)> show_fps_on_click = [&](std::string option) {
629 configuration.set_value(
"graphics",
"show_fps", option);
635 on_off_options, show_fps_on_click, dropdown_on_hover);
637 std::function<void(std::string)> show_pos_on_click = [&](std::string option) {
638 configuration.set_value(
"graphics",
"show_pos", option);
644 on_off_options, show_pos_on_click, dropdown_on_hover);
656 UI create_advanced_settings_ui() {
658 vertex_geometry::Rectangle main_settings_rect = settings_menu.at(1);
659 vertex_geometry::Grid main_settings_grid(7, 3, main_settings_rect);
661 vertex_geometry::Grid advanced_settings_grid(3, 3, main_settings_rect);
662 UI
advanced_settings_ui(-0.1, batcher.absolute_position_with_colored_vertex_shader_batcher.object_id_generator);
663 advanced_settings_ui.add_textbox(
"display tick time expendature", advanced_settings_grid.get_at(0, 0),