view_info.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved
  2. * See the LICENSE file for information about the license. */
  3. #include "app.h"
  4. enum {
  5. SubViewInfoMain,
  6. SubViewInfoSave,
  7. SubViewInfoLast, /* Just a sentinel. */
  8. };
  9. /* Our view private data. */
  10. typedef struct {
  11. /* Our save view displays an oscilloscope-alike resampled signal,
  12. * so that the user can see what they are saving. With left/right
  13. * you can move to next rows. Here we store where we are. */
  14. uint32_t signal_display_start_row;
  15. } InfoViewPrivData;
  16. /* Render the view with the detected message information. */
  17. static void render_subview_main(Canvas *const canvas, ProtoViewApp *app) {
  18. /* Protocol name as title. */
  19. canvas_set_font(canvas, FontPrimary);
  20. uint8_t y = 8, lineheight = 10;
  21. canvas_draw_str(canvas, 0, y, app->msg_info->name);
  22. y += lineheight;
  23. /* Info fields. */
  24. char buf[128];
  25. canvas_set_font(canvas, FontSecondary);
  26. if (app->msg_info->raw[0]) {
  27. snprintf(buf,sizeof(buf),"Raw: %s", app->msg_info->raw);
  28. canvas_draw_str(canvas, 0, y, buf);
  29. y += lineheight;
  30. }
  31. canvas_draw_str(canvas, 0, y, app->msg_info->info1); y += lineheight;
  32. canvas_draw_str(canvas, 0, y, app->msg_info->info2); y += lineheight;
  33. canvas_draw_str(canvas, 0, y, app->msg_info->info3); y += lineheight;
  34. canvas_draw_str(canvas, 0, y, app->msg_info->info4); y += lineheight;
  35. }
  36. /* Render view with save option. */
  37. static void render_subview_save(Canvas *const canvas, ProtoViewApp *app) {
  38. InfoViewPrivData *privdata = app->view_privdata;
  39. /* Display our signal in digital form: here we don't show the
  40. * signal with the exact timing of the received samples, but as it
  41. * is in its logic form, in exact multiples of the short pulse length. */
  42. uint8_t rows = 6;
  43. uint8_t rowheight = 11;
  44. uint8_t bitwidth = 4;
  45. uint8_t bitheight = 5;
  46. uint32_t idx = privdata->signal_display_start_row * (128/4);
  47. bool prevbit = false;
  48. for (uint8_t y = bitheight+12; y <= rows*rowheight; y += rowheight) {
  49. for (uint8_t x = 0; x < 128; x += 4) {
  50. bool bit = bitmap_get(app->msg_info->bits,
  51. app->msg_info->bits_bytes,idx);
  52. uint8_t prevy = y + prevbit*(bitheight*-1) - 1;
  53. uint8_t thisy = y + bit*(bitheight*-1) - 1;
  54. canvas_draw_line(canvas,x,prevy,x,thisy);
  55. canvas_draw_line(canvas,x,thisy,x+bitwidth-1,thisy);
  56. prevbit = bit;
  57. if (idx >= app->msg_info->pulses_count) {
  58. canvas_set_color(canvas, ColorWhite);
  59. canvas_draw_dot(canvas, x+1,thisy);
  60. canvas_draw_dot(canvas, x+3,thisy);
  61. canvas_set_color(canvas, ColorBlack);
  62. }
  63. idx++; // Draw next bit
  64. }
  65. }
  66. canvas_set_font(canvas, FontSecondary);
  67. canvas_draw_str(canvas, 0, 6, "ok: save, < >: slide rows");
  68. }
  69. /* Render the selected subview of this view. */
  70. void render_view_info(Canvas *const canvas, ProtoViewApp *app) {
  71. if (app->signal_decoded == false) {
  72. canvas_set_font(canvas, FontSecondary);
  73. canvas_draw_str(canvas, 30,36,"No signal decoded");
  74. return;
  75. }
  76. show_available_subviews(canvas,app,SubViewInfoLast);
  77. switch(app->current_subview[app->current_view]) {
  78. case SubViewInfoMain: render_subview_main(canvas,app); break;
  79. case SubViewInfoSave: render_subview_save(canvas,app); break;
  80. }
  81. }
  82. /* Handle input for the info view. */
  83. void process_input_info(ProtoViewApp *app, InputEvent input) {
  84. if (process_subview_updown(app,input,SubViewInfoLast)) return;
  85. InfoViewPrivData *privdata = app->view_privdata;
  86. int subview = get_current_subview(app);
  87. /* Main subview. */
  88. if (subview == SubViewInfoMain) {
  89. if (input.type == InputTypeShort && input.key == InputKeyOk) {
  90. /* Reset the current sample to capture the next. */
  91. reset_current_signal(app);
  92. }
  93. } else if (subview == SubViewInfoSave) {
  94. /* Save subview. */
  95. if (input.type == InputTypePress && input.key == InputKeyRight) {
  96. privdata->signal_display_start_row++;
  97. } else if (input.type == InputTypePress && input.key == InputKeyLeft) {
  98. if (privdata->signal_display_start_row != 0)
  99. privdata->signal_display_start_row--;
  100. }
  101. }
  102. }