multi_converter_mode_select.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include "multi_converter_mode_select.h"
  2. #define MULTI_CONVERTER_LIST_ENTRIES_COUNT 3
  3. #define MULTI_CONVERTER_INFO_STRING_FROM "FROM:"
  4. #define MULTI_CONVERTER_INFO_STRING_TO "TO:"
  5. #define MULTI_CONVERTER_INFO_STRING_OK "OK: Change"
  6. #define MULTI_CONVERTER_INFO_STRING_BACK "BACK: Cancel"
  7. void multi_converter_mode_select_draw_destination_offset(
  8. uint8_t x,
  9. uint8_t y,
  10. int8_t d,
  11. Canvas* const canvas,
  12. const MultiConverterState* multi_converter_state) {
  13. int i = 1;
  14. while(
  15. i <
  16. MULTI_CONVERTER_AVAILABLE_UNITS) { // in case there's no match, to avoid an endless loop (in theory shouldn't happen, but...)
  17. int ut = multi_converter_get_unit_type_offset(
  18. (multi_converter_state->select).selected_unit_type_dest, i * d);
  19. if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig]
  20. .allowed_function(ut) &&
  21. (multi_converter_state->select).selected_unit_type_orig != ut) {
  22. canvas_draw_str(canvas, x, y, multi_converter_available_units[ut].name);
  23. break;
  24. }
  25. i++;
  26. }
  27. }
  28. void multi_converter_mode_select_draw_selected_unit(
  29. uint8_t x,
  30. uint8_t y,
  31. MultiConverterUnitType unit_type,
  32. Canvas* const canvas) {
  33. canvas_draw_box(
  34. canvas,
  35. x - 2,
  36. y - 10,
  37. canvas_string_width(canvas, multi_converter_available_units[unit_type].name) + 4,
  38. 13);
  39. canvas_set_color(canvas, ColorWhite);
  40. canvas_draw_str(canvas, x, y, multi_converter_available_units[unit_type].name);
  41. canvas_set_color(canvas, ColorBlack);
  42. }
  43. void multi_converter_mode_select_draw(
  44. Canvas* const canvas,
  45. const MultiConverterState* multi_converter_state) {
  46. int y = 10;
  47. int x = 10;
  48. canvas_set_color(canvas, ColorBlack);
  49. // FROM
  50. canvas_set_font(canvas, FontPrimary);
  51. canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_FROM);
  52. canvas_set_font(canvas, FontSecondary);
  53. // offset -1
  54. y += 12;
  55. canvas_draw_str(
  56. canvas,
  57. x,
  58. y,
  59. multi_converter_available_units[multi_converter_get_unit_type_offset(
  60. (multi_converter_state->select).selected_unit_type_orig,
  61. -1)]
  62. .name);
  63. // current selected element
  64. y += 12;
  65. multi_converter_mode_select_draw_selected_unit(
  66. x, y, (multi_converter_state->select).selected_unit_type_orig, canvas);
  67. if((multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">");
  68. // offset +1
  69. y += 12;
  70. canvas_draw_str(
  71. canvas,
  72. x,
  73. y,
  74. multi_converter_available_units[multi_converter_get_unit_type_offset(
  75. (multi_converter_state->select).selected_unit_type_orig,
  76. 1)]
  77. .name);
  78. // TO
  79. y = 10;
  80. x = 70;
  81. canvas_set_font(canvas, FontPrimary);
  82. canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_TO);
  83. canvas_set_font(canvas, FontSecondary);
  84. // offset -1: go back from current selected destination and find the first one valid (even if it's itself)
  85. y += 12;
  86. multi_converter_mode_select_draw_destination_offset(x, y, -1, canvas, multi_converter_state);
  87. // current selected element
  88. y += 12;
  89. multi_converter_mode_select_draw_selected_unit(
  90. x, y, (multi_converter_state->select).selected_unit_type_dest, canvas);
  91. if(!(multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">");
  92. // offset +1: same but on the opposite direction
  93. y += 12;
  94. multi_converter_mode_select_draw_destination_offset(x, y, 1, canvas, multi_converter_state);
  95. // OK / CANCEL
  96. canvas_set_color(canvas, ColorBlack);
  97. canvas_draw_box(
  98. canvas, 0, 64 - 12, canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_OK) + 4, 12);
  99. canvas_draw_box(
  100. canvas,
  101. 128 - 4 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK),
  102. 64 - 12,
  103. canvas_string_width(canvas, "BACK: Cancel") + 4,
  104. 12);
  105. canvas_set_color(canvas, ColorWhite);
  106. canvas_draw_str(canvas, 2, 64 - 3, MULTI_CONVERTER_INFO_STRING_OK);
  107. canvas_draw_str(
  108. canvas,
  109. 128 - 2 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK),
  110. 64 - 3,
  111. MULTI_CONVERTER_INFO_STRING_BACK);
  112. }
  113. void multi_converter_mode_select_reset(MultiConverterState* const multi_converter_state) {
  114. // initial pre-selected values are equal to the current selected values
  115. (multi_converter_state->select).selected_unit_type_orig =
  116. multi_converter_state->unit_type_orig;
  117. (multi_converter_state->select).selected_unit_type_dest =
  118. multi_converter_state->unit_type_dest;
  119. (multi_converter_state->select).select_orig = 1;
  120. }
  121. MultiConverterModeTrigger multi_converter_mode_select_exit(
  122. uint8_t save_changes,
  123. MultiConverterState* const multi_converter_state) {
  124. if(save_changes) {
  125. multi_converter_state->unit_type_dest =
  126. (multi_converter_state->select).selected_unit_type_dest;
  127. if(multi_converter_state->unit_type_orig ==
  128. (multi_converter_state->select).selected_unit_type_orig) {
  129. // if the ORIGIN unit didn't changed, just trigger the convert
  130. return Convert;
  131. } else {
  132. multi_converter_state->unit_type_orig =
  133. (multi_converter_state->select).selected_unit_type_orig;
  134. multi_converter_state->unit_type_dest =
  135. (multi_converter_state->select).selected_unit_type_dest;
  136. return Reset;
  137. }
  138. }
  139. return None;
  140. }
  141. void multi_converter_mode_select_switch(MultiConverterState* const multi_converter_state) {
  142. (multi_converter_state->select).select_orig ^= 1;
  143. }
  144. void multi_converter_mode_select_change_unit(
  145. int8_t direction,
  146. MultiConverterState* const multi_converter_state) {
  147. MultiConverterUnitType d;
  148. if((multi_converter_state->select).select_orig) {
  149. (multi_converter_state->select).selected_unit_type_orig =
  150. multi_converter_get_unit_type_offset(
  151. (multi_converter_state->select).selected_unit_type_orig, direction);
  152. d = (multi_converter_state->select).selected_unit_type_dest;
  153. } else {
  154. d = ((multi_converter_state->select).selected_unit_type_dest + direction) %
  155. MULTI_CONVERTER_AVAILABLE_UNITS;
  156. }
  157. // check each unit with the ORIGIN allowed_function() to make sure we're selecting a valid DESTINATION
  158. // (when changing the ORIGIN unit the DIRECTION in which we'll switch the DESTINATION will be the SAME);
  159. // also notice that ORIGIN must be DIFFERENT than DESTINATION
  160. int i = 0;
  161. while(i < MULTI_CONVERTER_AVAILABLE_UNITS) {
  162. if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig]
  163. .allowed_function(d) &&
  164. (multi_converter_state->select).selected_unit_type_orig != d) {
  165. (multi_converter_state->select).selected_unit_type_dest = d;
  166. break;
  167. }
  168. d = multi_converter_get_unit_type_offset(d, direction);
  169. i++;
  170. }
  171. }