select_pokemon.c 5.0 KB

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