eth_view_process.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "eth_view_process.h"
  2. #include "eth_worker.h"
  3. #include "eth_worker_i.h"
  4. #include "finik_eth_icons.h"
  5. #include <furi_hal.h>
  6. #include <gui/gui.h>
  7. #include <gui/canvas.h>
  8. #include <string.h>
  9. #include "u8g2.h"
  10. #define TAG "EthView"
  11. EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type) {
  12. EthViewProcess* evp = malloc(sizeof(EthViewProcess));
  13. evp->type = type;
  14. evp->autofill = 1;
  15. evp->carriage = 0;
  16. evp->position = 0;
  17. evp->x = 27;
  18. evp->y = 6;
  19. if(type == EthWorkerProcessInit) {
  20. evp->y += 22;
  21. evp->draw_struct = malloc(sizeof(EthViewDrawInit));
  22. memset(evp->draw_struct, 0, sizeof(EthViewDrawInit));
  23. }
  24. return evp;
  25. }
  26. void ethernet_view_process_free(EthViewProcess* evp) {
  27. if(evp->type == EthWorkerProcessInit) {
  28. free(evp->draw_struct);
  29. }
  30. free(evp);
  31. }
  32. static void draw_hex_digit(Canvas* canvas, uint8_t x, uint8_t y, uint8_t digit) {
  33. char digit_str[] = "0";
  34. if(digit < 0xA) {
  35. digit_str[0] += digit;
  36. } else if(digit < 0x10) {
  37. digit_str[0] = 'A';
  38. digit_str[0] += digit - 0xA;
  39. } else {
  40. return;
  41. }
  42. canvas_draw_str(canvas, x, y, digit_str);
  43. }
  44. void ethernet_view_process_draw(EthViewProcess* process, Canvas* canvas) {
  45. furi_assert(canvas);
  46. furi_assert(process);
  47. canvas_set_font(canvas, FontSecondary);
  48. const uint8_t x = process->x;
  49. const uint8_t y = process->y;
  50. const uint8_t str_height = 11;
  51. const uint8_t str_count = (64 - y) / str_height;
  52. uint8_t carriage = process->carriage;
  53. uint8_t position = process->position;
  54. if(process->autofill) {
  55. position = (carriage + SCREEN_STRINGS_COUNT - str_count) % SCREEN_STRINGS_COUNT;
  56. process->position = position;
  57. }
  58. for(uint8_t i = 0; i < str_count; ++i) {
  59. uint8_t y1 = y + (i + 1) * str_height;
  60. canvas_draw_str(canvas, x, y1, process->fifo[(position + i) % SCREEN_STRINGS_COUNT]);
  61. }
  62. if(process->type == EthWorkerProcessInit) {
  63. uint8_t editing = process->editing;
  64. canvas_draw_icon(canvas, 27, 10, &I_init_100x19px);
  65. for(uint8_t i = 0; i < 6; ++i) {
  66. uint8_t x1 = 29 + i * 17;
  67. uint8_t x2 = x1 + 6;
  68. uint8_t mac = ((EthViewDrawInit*)process->draw_struct)->mac[i];
  69. uint8_t octet = ((EthViewDrawInit*)process->draw_struct)->current_octet;
  70. draw_hex_digit(canvas, x1, 25, (mac & 0x0F));
  71. draw_hex_digit(canvas, x2, 25, (mac & 0xF0) >> 4);
  72. if(editing && (octet / 2 == i)) {
  73. uint8_t x = octet & 1 ? x2 : x1;
  74. canvas_draw_line(canvas, x, 26, x + 4, 26);
  75. canvas_draw_line(canvas, x, 27, x + 4, 27);
  76. }
  77. }
  78. }
  79. }
  80. static void mac_change_hex_digit(uint8_t* mac, uint8_t octet, int8_t diff) {
  81. uint8_t digit = (octet & 1) ? (mac[octet / 2] >> 4) : (mac[octet / 2]);
  82. digit = (digit + diff) & 0xF;
  83. mac[octet / 2] = (mac[octet / 2] & ((octet & 1) ? 0x0F : 0xF0)) |
  84. (digit << ((octet & 1) ? 4 : 0));
  85. }
  86. void ethernet_view_process_keyevent(EthViewProcess* process, InputKey key) {
  87. furi_assert(process);
  88. if(process->type == EthWorkerProcessInit) {
  89. uint8_t octet = ((EthViewDrawInit*)process->draw_struct)->current_octet;
  90. uint8_t* mac = ((EthViewDrawInit*)process->draw_struct)->mac;
  91. if(key == InputKeyLeft) {
  92. if(octet > 0) octet -= 1;
  93. } else if(key == InputKeyRight) {
  94. if(octet < 12) octet += 1;
  95. } else if(key == InputKeyUp) {
  96. mac_change_hex_digit(mac, octet, 1);
  97. } else if(key == InputKeyDown) {
  98. mac_change_hex_digit(mac, octet, -1);
  99. } else if(key == InputKeyOk) {
  100. process->editing = 0;
  101. }
  102. ((EthViewDrawInit*)process->draw_struct)->current_octet = octet;
  103. }
  104. }
  105. void ethernet_view_process_move(EthViewProcess* process, int8_t shift) {
  106. furi_assert(process);
  107. uint8_t position = process->position;
  108. if(shift <= -SCREEN_STRINGS_COUNT) {
  109. position = 0;
  110. } else if(shift >= SCREEN_STRINGS_COUNT) {
  111. position = process->carriage - 1;
  112. } else {
  113. position = (position + (SCREEN_STRINGS_COUNT + shift)) % SCREEN_STRINGS_COUNT;
  114. }
  115. process->position = position;
  116. process->autofill = !shift;
  117. }
  118. void ethernet_view_process_autofill(EthViewProcess* process, uint8_t state) {
  119. furi_assert(process);
  120. process->autofill = state;
  121. }
  122. static uint16_t get_string_with_width(const char* str, uint16_t width) {
  123. u8g2_t canvas_memory;
  124. Canvas* canvas = (Canvas*)&canvas_memory; // grazniy hack
  125. canvas_set_font(canvas, FontSecondary);
  126. uint8_t end = 0;
  127. char copy[SCREEN_SYMBOLS_WIDTH + 1] = {0};
  128. for(;;) {
  129. if(str[end] == '\0') {
  130. break;
  131. }
  132. if(end == SCREEN_SYMBOLS_WIDTH) {
  133. break;
  134. }
  135. copy[end] = str[end];
  136. if(canvas_string_width(canvas, copy) > width) {
  137. end -= 1;
  138. break;
  139. }
  140. end += 1;
  141. }
  142. return end;
  143. }
  144. void ethernet_view_process_print(EthViewProcess* process, const char* str) {
  145. furi_assert(process);
  146. uint16_t max_width = 126 - process->x;
  147. uint16_t ptr = 0;
  148. uint16_t len = strlen(str);
  149. while(ptr < len) {
  150. uint16_t start = ptr;
  151. ptr += get_string_with_width(str + ptr, max_width);
  152. uint8_t carriage = process->carriage;
  153. uint8_t carriage1 = (carriage + 1) % SCREEN_STRINGS_COUNT;
  154. uint8_t carriage2 = (carriage + 2) % SCREEN_STRINGS_COUNT;
  155. FURI_LOG_I(TAG, "print %d %d %d %d %d", max_width, len, start, carriage, carriage1);
  156. memset(process->fifo[carriage], 0, SCREEN_SYMBOLS_WIDTH);
  157. memset(process->fifo[carriage1], 0, SCREEN_SYMBOLS_WIDTH);
  158. memset(process->fifo[carriage2], 0, SCREEN_SYMBOLS_WIDTH);
  159. memcpy(process->fifo[carriage], str + start, ptr - start);
  160. process->carriage = carriage1;
  161. }
  162. }