pokemon_name_input.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include <ctype.h>
  2. #include <furi.h>
  3. #include <gui/modules/text_input.h>
  4. #include <gui/view_dispatcher.h>
  5. #include <stdlib.h>
  6. #include <src/include/pokemon_app.h>
  7. #include <src/include/pokemon_data.h>
  8. #include <src/include/pokemon_char_encode.h>
  9. #include <src/include/pokemon_attribute.h>
  10. #include <src/scenes/include/pokemon_scene.h>
  11. static char name_buf[LEN_NAME_BUF];
  12. /* NOTE:
  13. * It would be nice if we could cleanly default to the pokemon's name as their
  14. * name. The issue is that if you enter a blank line to text input, it does
  15. * call this function, but returning true does nothing. However, I've found that
  16. * if you check for the first char of the buffer being \0, you can then set the
  17. * buffer and then return true. This has the effect of staying in the text_input
  18. * screen, but, prepopulating the text entry with the buffer AND staying on the
  19. * save button.
  20. */
  21. static bool select_name_input_validator(const char* text, FuriString* error, void* context) {
  22. PokemonFap* pokemon_fap = (PokemonFap*)context;
  23. uint32_t state =
  24. scene_manager_get_scene_state(pokemon_fap->scene_manager, PokemonSceneNickname);
  25. unsigned int i;
  26. /* A blank field for the pokemon nickname means revert to default name */
  27. if(text[0] == '\0' && state == PokemonSceneNickname) {
  28. /* Get the pokemon's name and populate our buffer with it */
  29. /* TODO: Nidoran M/F are still a problem with this. */
  30. pokemon_default_nickname_set(name_buf, pokemon_fap->pdata, sizeof(name_buf));
  31. return true;
  32. }
  33. /* Check to ensure no digits in OT name/nickname */
  34. for(i = 0; i < strlen(text); i++) {
  35. if(isdigit((unsigned int)text[i])) {
  36. furi_string_printf(error, "Name cannot\ncontain\nnumbers!");
  37. return false;
  38. }
  39. }
  40. /* Check for Unown setting is a character */
  41. if(state == PokemonSceneUnownForm) {
  42. if(!isalpha((int)text[0])) {
  43. furi_string_printf(error, "Form must\nbe a single\nletter!");
  44. return false;
  45. }
  46. }
  47. switch(state) {
  48. case PokemonSceneNickname:
  49. pokemon_name_set(pokemon_fap->pdata, STAT_NICKNAME, (char*)text);
  50. break;
  51. case PokemonSceneOTName:
  52. pokemon_name_set(pokemon_fap->pdata, STAT_OT_NAME, (char*)text);
  53. break;
  54. case PokemonSceneUnownForm:
  55. unown_form_set(pokemon_fap->pdata, text[0]);
  56. break;
  57. default:
  58. furi_crash("Invalid scene");
  59. break;
  60. }
  61. return true;
  62. }
  63. static void select_name_input_callback(void* context) {
  64. PokemonFap* pokemon_fap = (PokemonFap*)context;
  65. scene_manager_previous_scene(pokemon_fap->scene_manager);
  66. }
  67. void pokemon_scene_select_name_on_enter(void* context) {
  68. PokemonFap* pokemon_fap = (PokemonFap*)context;
  69. uint32_t state =
  70. scene_manager_get_scene_state(pokemon_fap->scene_manager, PokemonSceneNickname);
  71. char* header;
  72. int len;
  73. DataStat stat;
  74. switch(state) {
  75. case PokemonSceneNickname:
  76. header = "Nickname (none for default)";
  77. len = LEN_NICKNAME;
  78. stat = STAT_NICKNAME;
  79. break;
  80. case PokemonSceneOTName:
  81. header = "Enter OT Name";
  82. len = LEN_OT_NAME;
  83. stat = STAT_OT_NAME;
  84. break;
  85. case PokemonSceneUnownForm:
  86. header = "Enter Unown Letter Form";
  87. len = 2;
  88. stat = STAT_OT_NAME;
  89. break;
  90. default:
  91. furi_crash("Name: invalid state");
  92. break;
  93. }
  94. if(state == PokemonSceneUnownForm) {
  95. /* Put the current letter in the buffer */
  96. name_buf[0] = unown_form_get(pokemon_fap->pdata);
  97. name_buf[1] = '\0';
  98. } else {
  99. pokemon_name_get(pokemon_fap->pdata, stat, name_buf, len);
  100. }
  101. text_input_reset(pokemon_fap->text_input);
  102. text_input_set_validator(pokemon_fap->text_input, select_name_input_validator, pokemon_fap);
  103. text_input_set_result_callback(
  104. pokemon_fap->text_input, select_name_input_callback, pokemon_fap, name_buf, len, true);
  105. text_input_set_header_text(pokemon_fap->text_input, header);
  106. view_dispatcher_add_view(
  107. pokemon_fap->view_dispatcher, AppViewOpts, text_input_get_view(pokemon_fap->text_input));
  108. view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewOpts);
  109. }
  110. bool pokemon_scene_select_name_on_event(void* context, SceneManagerEvent event) {
  111. UNUSED(context);
  112. UNUSED(event);
  113. return false;
  114. }
  115. void pokemon_scene_select_name_on_exit(void* context) {
  116. PokemonFap* pokemon_fap = (PokemonFap*)context;
  117. view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewMainMenu);
  118. view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewOpts);
  119. }