mass_storage_view.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "mass_storage_view.h"
  2. #include "../mass_storage_app_i.h"
  3. #include <gui/elements.h>
  4. struct MassStorage {
  5. View* view;
  6. };
  7. typedef struct {
  8. FuriString *file_name, *status_string;
  9. uint32_t read_speed, write_speed;
  10. uint32_t bytes_read, bytes_written;
  11. uint32_t update_time;
  12. } MassStorageModel;
  13. static void append_suffixed_byte_count(FuriString* string, uint32_t count) {
  14. if(count < 1024) {
  15. furi_string_cat_printf(string, "%luB", count);
  16. } else if(count < 1024 * 1024) {
  17. furi_string_cat_printf(string, "%luK", count / 1024);
  18. } else if(count < 1024 * 1024 * 1024) {
  19. furi_string_cat_printf(string, "%.1fM", (double)count / (1024 * 1024));
  20. } else {
  21. furi_string_cat_printf(string, "%.1fG", (double)count / (1024 * 1024 * 1024));
  22. }
  23. }
  24. static void mass_storage_draw_callback(Canvas* canvas, void* _model) {
  25. MassStorageModel* model = _model;
  26. canvas_draw_icon(canvas, 8, 14, &I_Drive_112x35);
  27. canvas_set_font(canvas, FontPrimary);
  28. canvas_draw_str_aligned(
  29. canvas, canvas_width(canvas) / 2, 0, AlignCenter, AlignTop, "USB Mass Storage");
  30. canvas_set_font(canvas, FontBatteryPercent);
  31. elements_string_fit_width(canvas, model->file_name, 89 - 2);
  32. canvas_draw_str_aligned(
  33. canvas, 92, 24, AlignRight, AlignBottom, furi_string_get_cstr(model->file_name));
  34. furi_string_set_str(model->status_string, "R:");
  35. append_suffixed_byte_count(model->status_string, model->bytes_read);
  36. if(model->read_speed) {
  37. furi_string_cat_str(model->status_string, "/");
  38. append_suffixed_byte_count(model->status_string, model->read_speed);
  39. furi_string_cat_str(model->status_string, "s");
  40. }
  41. canvas_draw_str(canvas, 14, 34, furi_string_get_cstr(model->status_string));
  42. furi_string_set_str(model->status_string, "W:");
  43. append_suffixed_byte_count(model->status_string, model->bytes_written);
  44. if(model->write_speed) {
  45. furi_string_cat_str(model->status_string, "/");
  46. append_suffixed_byte_count(model->status_string, model->write_speed);
  47. furi_string_cat_str(model->status_string, "s");
  48. }
  49. canvas_draw_str(canvas, 14, 43, furi_string_get_cstr(model->status_string));
  50. }
  51. MassStorage* mass_storage_alloc() {
  52. MassStorage* mass_storage = malloc(sizeof(MassStorage));
  53. mass_storage->view = view_alloc();
  54. view_allocate_model(mass_storage->view, ViewModelTypeLocking, sizeof(MassStorageModel));
  55. with_view_model(
  56. mass_storage->view,
  57. MassStorageModel * model,
  58. {
  59. model->file_name = furi_string_alloc();
  60. model->status_string = furi_string_alloc();
  61. },
  62. false);
  63. view_set_context(mass_storage->view, mass_storage);
  64. view_set_draw_callback(mass_storage->view, mass_storage_draw_callback);
  65. return mass_storage;
  66. }
  67. void mass_storage_free(MassStorage* mass_storage) {
  68. furi_assert(mass_storage);
  69. with_view_model(
  70. mass_storage->view,
  71. MassStorageModel * model,
  72. {
  73. furi_string_free(model->file_name);
  74. furi_string_free(model->status_string);
  75. },
  76. false);
  77. view_free(mass_storage->view);
  78. free(mass_storage);
  79. }
  80. View* mass_storage_get_view(MassStorage* mass_storage) {
  81. furi_assert(mass_storage);
  82. return mass_storage->view;
  83. }
  84. void mass_storage_set_file_name(MassStorage* mass_storage, FuriString* name) {
  85. furi_assert(name);
  86. with_view_model(
  87. mass_storage->view,
  88. MassStorageModel * model,
  89. { furi_string_set(model->file_name, name); },
  90. true);
  91. }
  92. void mass_storage_set_stats(MassStorage* mass_storage, uint32_t read, uint32_t written) {
  93. with_view_model(
  94. mass_storage->view,
  95. MassStorageModel * model,
  96. {
  97. uint32_t now = furi_get_tick();
  98. model->read_speed = (read - model->bytes_read) * 1000 / (now - model->update_time);
  99. model->write_speed =
  100. (written - model->bytes_written) * 1000 / (now - model->update_time);
  101. model->bytes_read = read;
  102. model->bytes_written = written;
  103. model->update_time = now;
  104. },
  105. true);
  106. }