diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ddf36d1b6..7a1b737a3 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -330,6 +330,7 @@ SystemStatusView::SystemStatusView( audio::output::stop(); audio::output::update_audio_mute(); + refresh(); } @@ -761,10 +762,10 @@ static void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc) } // clang-format off -void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t notice_pos) { +void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos) { auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav); if (externalItems.empty()) { - grid.insert_item({"Notice!", + grid.insert_item({"ExtApp\nError", Theme::getInstance()->error_dark->foreground, nullptr, [&nav]() { @@ -774,7 +775,7 @@ void add_external_items(NavigationView& nav, app_location_t location, BtnGridVie "see Mayhem wiki and copy apps\n" "to " + apps_dir.string() + " folder of SD card."); }}, - notice_pos); + error_tile_pos); } else { std::sort(externalItems.begin(), externalItems.end(), [](const auto &a, const auto &b) { @@ -795,6 +796,12 @@ void add_external_items(NavigationView& nav, app_location_t location, BtnGridVie } // clang-format on +bool verify_sdcard_format() { + FATFS* fs = &sd_card::fs; + return (fs->fs_type == FS_FAT32) || !(sd_card::status() == sd_card::Status::Mounted); + /* ^ to satisfy those users that not use an sd*/ +} + /* ReceiversMenuView *****************************************************/ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) @@ -866,8 +873,13 @@ SystemMenuView::SystemMenuView(NavigationView& nav) } void SystemMenuView::on_populate() { + if (!verify_sdcard_format()) { + add_item({"SDCard Error", Theme::getInstance()->error_dark->foreground, nullptr, [this]() { + nav_.display_modal("Error", "SD Card is not FAT32,\nformat to FAT32 on PC"); + }}); + } add_apps(nav_, *this, HOME); - add_external_items(nav_, app_location_t::HOME, *this, 2); + add_external_items(nav_, app_location_t::HOME, *this, 0); add_item({"HackRF", Theme::getInstance()->fg_cyan->foreground, &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }}); } diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index e68614544..52548978a 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -197,6 +197,7 @@ class SystemStatusView : public View { static constexpr auto default_title = ""; bool batt_was_inited = false; // if the battery was off on tart, but later turned on. bool batt_info_up = false; // to prevent show multiple batt info dialog + NavigationView& nav_; Rectangle backdrop{ diff --git a/firmware/application/ui_sd_card_debug.cpp b/firmware/application/ui_sd_card_debug.cpp index 13363727c..a5cda13e7 100644 --- a/firmware/application/ui_sd_card_debug.cpp +++ b/firmware/application/ui_sd_card_debug.cpp @@ -240,21 +240,16 @@ namespace ui { SDCardDebugView::SDCardDebugView(NavigationView& nav) { add_children({ - &text_title, - &text_csd_title, + &labels, + &text_format, &text_csd_value_3, &text_csd_value_2, &text_csd_value_1, &text_csd_value_0, - &text_bus_width_title, &text_bus_width_value, - &text_card_type_title, &text_card_type_value, - &text_block_size_title, &text_block_size_value, - &text_block_count_title, &text_block_count_value, - &text_capacity_title, &text_capacity_value, &text_test_write_time_title, &text_test_write_time_value, @@ -374,6 +369,14 @@ void SDCardDebugView::on_status(const sd_card::Status) { text_csd_value_1.set(to_string_hex(csd[1], 8)); text_csd_value_0.set(to_string_hex(csd[0], 8)); + text_format.set(fetch_sdcard_format()); + if (fetch_sdcard_format().find("FAT32") != std::string::npos) { + // to satisfy the intendent style in this app, the text contains padding space, thus can't use == + text_format.set_style(Theme::getInstance()->fg_green); + } else { + text_format.set_style(Theme::getInstance()->error_dark); + } + BlockDeviceInfo block_device_info; if (sdcGetInfo(&SDCD1, &block_device_info) == CH_SUCCESS) { text_block_size_value.set(to_string_dec_uint(block_device_info.blk_size, 5)); @@ -447,4 +450,38 @@ void SDCardDebugView::on_test() { } } +std::string SDCardDebugView::fetch_sdcard_format() { + const size_t max_len = sizeof("Undefined: 255") + 1; + + auto padding = [max_len](std::string s) { + if (s.length() < max_len) { + return std::string(max_len - s.length(), ' ') + s; + } + return s; + }; + + FATFS* fs = &sd_card::fs; + std::string resault; + + switch (fs->fs_type) { + case FS_FAT12: + resault = "FAT12"; + break; + case FS_FAT16: + resault = "FAT16"; + break; + case FS_FAT32: + resault = "FAT32"; + break; + case FS_EXFAT: // TODO: a bug from filesystem can't detect exfat, issue not from here + resault = "ExFAT"; + break; + default: + resault = "Undefined: " + to_string_dec_uint(fs->fs_type, 1); + break; + } + + return padding(resault); +} + } /* namespace ui */ diff --git a/firmware/application/ui_sd_card_debug.hpp b/firmware/application/ui_sd_card_debug.hpp index 4590418e2..cf2b60b66 100644 --- a/firmware/application/ui_sd_card_debug.hpp +++ b/firmware/application/ui_sd_card_debug.hpp @@ -45,15 +45,23 @@ class SDCardDebugView : public View { void on_status(const sd_card::Status status); void on_test(); + std::string fetch_sdcard_format(); + + Labels labels{ + {{0 * 8, 1 * 16}, "Format", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 3 * 16}, "CSD", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 5 * 16}, "Bus width", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 6 * 16}, "Card type", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 8 * 16}, "Block size", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 9 * 16}, "Block count", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 10 * 16}, "Capacity", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 5 * 16}, "Bus width", Theme::getInstance()->fg_light->foreground}, - Text text_title{ - {(240 - (7 * 8)) / 2, 1 * 16, (7 * 8), 16}, - "SD Card", }; - Text text_csd_title{ - {0, 3 * 16, (8 * 8), 16}, - "CSD", + Text text_format{ + {240 - ((sizeof("Undefined: 255") + 1) * 8), 1 * 16, (sizeof("Undefined: 255") + 1) * 8, 16}, + "Unknown", }; Text text_csd_value_3{ @@ -78,11 +86,6 @@ class SDCardDebugView : public View { static constexpr size_t bus_width_characters = 1; - Text text_bus_width_title{ - {0, 5 * 16, (9 * 8), 16}, - "Bus width", - }; - Text text_bus_width_value{ {240 - (bus_width_characters * 8), 5 * 16, (bus_width_characters * 8), 16}, "", @@ -90,11 +93,6 @@ class SDCardDebugView : public View { static constexpr size_t card_type_characters = 13; - Text text_card_type_title{ - {0, 6 * 16, (9 * 8), 16}, - "Card type", - }; - Text text_card_type_value{ {240 - (card_type_characters * 8), 6 * 16, (card_type_characters * 8), 16}, "", @@ -102,11 +100,6 @@ class SDCardDebugView : public View { static constexpr size_t block_size_characters = 5; - Text text_block_size_title{ - {0, 8 * 16, (10 * 8), 16}, - "Block size", - }; - Text text_block_size_value{ {240 - (block_size_characters * 8), 8 * 16, (block_size_characters * 8), 16}, "", @@ -114,11 +107,6 @@ class SDCardDebugView : public View { static constexpr size_t block_count_characters = 9; - Text text_block_count_title{ - {0, 9 * 16, (11 * 8), 16}, - "Block count", - }; - Text text_block_count_value{ {240 - (block_count_characters * 8), 9 * 16, (block_count_characters * 8), 16}, "", @@ -126,11 +114,6 @@ class SDCardDebugView : public View { static constexpr size_t capacity_characters = 10; - Text text_capacity_title{ - {0, 10 * 16, (8 * 8), 16}, - "Capacity", - }; - Text text_capacity_value{ {240 - (capacity_characters * 8), 10 * 16, (capacity_characters * 8), 16}, "", diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index 9f405bb95..745277076 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -1327,10 +1327,11 @@ void NewButton::paint(Painter& painter) { style.background); int y = r.top(); + if (bitmap_) { int offset_y = vertical_center_ ? (r.height() / 2) - (bitmap_->size.height() / 2) : 6; Point bmp_pos = {r.left() + (r.width() / 2) - (bitmap_->size.width() / 2), r.top() + offset_y}; - y += bitmap_->size.height() - offset_y; + y += bitmap_->size.height() + offset_y; painter.draw_bitmap( bmp_pos, @@ -1340,11 +1341,38 @@ void NewButton::paint(Painter& painter) { } if (!text_.empty()) { - const auto label_r = style.font.size_of(text_); - painter.draw_string( - {r.left() + (r.width() - label_r.width()) / 2, y + (r.height() - label_r.height()) / 2}, - style, - text_); + // multi line worker + std::vector lines; + size_t start = 0; + size_t end = 0; + + while ((end = text_.find('\n', start)) != std::string::npos) { + lines.push_back(text_.substr(start, end - start)); + start = end + 1; + } + lines.push_back(text_.substr(start)); + + const int line_height = style.font.line_height(); + const int total_text_height = lines.size() * line_height; + + // satisfy the situation that bitmap is nullptr + if (bitmap_) { + if (vertical_center_) { + y = r.top() + (r.height() - total_text_height) / 2; + } + } else { + y = r.top() + (r.height() - total_text_height) / 2; + } + + // draw worker + for (const auto& line : lines) { + const auto label_r = style.font.size_of(line); + painter.draw_string( + {r.left() + (r.width() - label_r.width()) / 2, y}, + style, + line); + y += line_height; + } } }