select_pokemon.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include <gui/elements.h>
  2. #include <pokemon_icons.h>
  3. #include "../scenes/pokemon_menu.h"
  4. #include "../pokemon_app.h"
  5. #include "../pokemon_data.h"
  6. struct select_model {
  7. uint8_t curr_pokemon;
  8. const void* pokemon_table;
  9. PokemonData* pdata;
  10. };
  11. /* Anonymous struct */
  12. struct select_ctx {
  13. View* view;
  14. PokemonData* pdata;
  15. SceneManager* scene_manager;
  16. };
  17. static void select_pokemon_render_callback(Canvas* canvas, void* model) {
  18. struct select_model* view_model = model;
  19. uint8_t curr_pokemon = view_model->curr_pokemon;
  20. char pokedex_num[5];
  21. snprintf(pokedex_num, sizeof(pokedex_num), "#%03d", curr_pokemon + 1);
  22. /* Update the bitmap in pdata if needed */
  23. pokemon_icon_get(view_model->pdata, curr_pokemon + 1);
  24. canvas_draw_xbm(
  25. canvas,
  26. 0,
  27. 0,
  28. view_model->pdata->bitmap->width,
  29. view_model->pdata->bitmap->height,
  30. view_model->pdata->bitmap->data);
  31. canvas_set_font(canvas, FontPrimary);
  32. canvas_draw_str_aligned(
  33. canvas,
  34. 58,
  35. 27,
  36. AlignLeft,
  37. AlignTop,
  38. table_stat_name_get(view_model->pokemon_table, curr_pokemon));
  39. canvas_set_font(canvas, FontSecondary);
  40. canvas_draw_str_aligned(canvas, 58, 38, AlignLeft, AlignTop, pokedex_num);
  41. elements_frame(canvas, 55, 0, 71, 18);
  42. canvas_draw_str_aligned(canvas, 90, 5, AlignCenter, AlignTop, "Select Pokemon");
  43. canvas_set_font(canvas, FontPrimary);
  44. elements_button_center(canvas, "OK");
  45. }
  46. static bool select_pokemon_input_callback(InputEvent* event, void* context) {
  47. struct select_ctx* select = (struct select_ctx*)context;
  48. bool consumed = false;
  49. uint8_t selected_pokemon;
  50. furi_assert(context);
  51. /* We only handle InputTypePress at the moment */
  52. if(event->type != InputTypePress) return consumed;
  53. with_view_model(
  54. select->view,
  55. struct select_model * model,
  56. { selected_pokemon = model->curr_pokemon; },
  57. false);
  58. switch(event->key) {
  59. /* Advance to next view with the selected pokemon */
  60. case InputKeyOk:
  61. pokemon_stat_set(select->pdata, STAT_NUM, NONE, selected_pokemon);
  62. scene_manager_previous_scene(select->scene_manager);
  63. consumed = true;
  64. break;
  65. /* Move back one through the pokedex listing */
  66. case InputKeyLeft:
  67. if(selected_pokemon == 0)
  68. selected_pokemon = select->pdata->dex_max;
  69. else
  70. selected_pokemon--;
  71. consumed = true;
  72. break;
  73. /* Move back ten through the pokemon listing, wrap to max pokemon on
  74. * underflow.
  75. */
  76. case InputKeyDown:
  77. if(selected_pokemon >= 10)
  78. selected_pokemon -= 10;
  79. else
  80. selected_pokemon = select->pdata->dex_max;
  81. consumed = true;
  82. break;
  83. /* Move forward one through the pokedex listing */
  84. case InputKeyRight:
  85. if(selected_pokemon == select->pdata->dex_max)
  86. selected_pokemon = 0;
  87. else
  88. selected_pokemon++;
  89. consumed = true;
  90. break;
  91. /* Move forward ten through the pokemon listing, wrap to min pokemon on
  92. * overflow.
  93. */
  94. case InputKeyUp:
  95. if(selected_pokemon <= (select->pdata->dex_max - 10))
  96. selected_pokemon += 10;
  97. else
  98. selected_pokemon = 0;
  99. consumed = true;
  100. break;
  101. default:
  102. // Do Nothing
  103. break;
  104. }
  105. with_view_model(
  106. select->view,
  107. struct select_model * model,
  108. { model->curr_pokemon = selected_pokemon; },
  109. true);
  110. return consumed;
  111. }
  112. void select_pokemon_enter_callback(void* context) {
  113. struct select_ctx* select = (struct select_ctx*)context;
  114. with_view_model(
  115. select->view,
  116. struct select_model * model,
  117. {
  118. model->curr_pokemon = pokemon_stat_get(select->pdata, STAT_NUM, NONE);
  119. model->pokemon_table = select->pdata->pokemon_table;
  120. model->pdata = select->pdata;
  121. },
  122. true);
  123. }
  124. void* select_pokemon_alloc(
  125. PokemonData* pdata,
  126. ViewDispatcher* view_dispatcher,
  127. SceneManager* scene_manager,
  128. uint32_t viewid) {
  129. furi_assert(pdata);
  130. struct select_ctx* select = malloc(sizeof(struct select_ctx));
  131. select->view = view_alloc();
  132. select->pdata = pdata;
  133. select->scene_manager = scene_manager;
  134. select->pdata = pdata;
  135. view_set_context(select->view, select);
  136. view_allocate_model(select->view, ViewModelTypeLockFree, sizeof(struct select_model));
  137. view_set_draw_callback(select->view, select_pokemon_render_callback);
  138. view_set_input_callback(select->view, select_pokemon_input_callback);
  139. view_set_enter_callback(select->view, select_pokemon_enter_callback);
  140. view_dispatcher_add_view(view_dispatcher, viewid, select->view);
  141. return select;
  142. }
  143. void select_pokemon_free(ViewDispatcher* view_dispatcher, uint32_t viewid, void* select_ctx) {
  144. struct select_ctx* select = (struct select_ctx*)select_ctx;
  145. view_dispatcher_remove_view(view_dispatcher, viewid);
  146. view_free(select->view);
  147. free(select);
  148. }