diff --git a/firmware/application/apps/ble_rx_app.hpp b/firmware/application/apps/ble_rx_app.hpp index 8cb21b189..7dfe95961 100644 --- a/firmware/application/apps/ble_rx_app.hpp +++ b/firmware/application/apps/ble_rx_app.hpp @@ -322,10 +322,10 @@ class BLERxView : public View { {UI_POS_X(21), UI_POS_Y(0)}}; RSSI rssi{ - {UI_POS_X(24), 0, UI_POS_WIDTH_REMAINING(6), 4}}; + {UI_POS_X(24), 0, UI_POS_WIDTH_REMAINING(24), 4}}; Channel channel{ - {UI_POS_X(24), 5, UI_POS_WIDTH_REMAINING(6), 4}}; + {UI_POS_X(24), 5, UI_POS_WIDTH_REMAINING(24), 4}}; Labels label_sort{ {{UI_POS_X(0), UI_POS_Y(1)}, "Sort:", Theme::getInstance()->fg_light->foreground}}; diff --git a/firmware/application/external/waterfall_designer/ui_waterfall_designer.cpp b/firmware/application/external/waterfall_designer/ui_waterfall_designer.cpp index e4d3da40c..f07272cce 100644 --- a/firmware/application/external/waterfall_designer/ui_waterfall_designer.cpp +++ b/firmware/application/external/waterfall_designer/ui_waterfall_designer.cpp @@ -193,15 +193,12 @@ void WaterfallDesignerView::on_profile_changed(std::filesystem::path new_profile auto reader = FileLineReader(playlist_file); for (const auto& line : reader) { + // remove empty lines + if (line == "\n" || line == "\r\n" || line == "\r") continue; profile_levels.push_back(line); } for (auto& line : profile_levels) { - // remove empty lines - if (line == "\n" || line == "\r\n" || line == "\r") { - profile_levels.erase(std::remove(profile_levels.begin(), profile_levels.end(), line), profile_levels.end()); - } - // remove line end \n etc if (line.length() > 0 && (line[line.length() - 1] == '\n' || line[line.length() - 1] == '\r')) { line = line.substr(0, line.length() - 1); diff --git a/firmware/application/gradient.cpp b/firmware/application/gradient.cpp index f8564526a..a2480a9cf 100644 --- a/firmware/application/gradient.cpp +++ b/firmware/application/gradient.cpp @@ -28,13 +28,11 @@ namespace fs = std::filesystem; const std::filesystem::path default_gradient_file = u"waterfall.txt"; Gradient::Gradient() { - prev_index = 0; - prev_r = 0; - prev_g = 0; - prev_b = 0; + step(0, 0, 0, 0); } void Gradient::set_default() { + step(0, 0, 0, 0); step(86, 0, 0, 255); step(171, 0, 255, 0); step(255, 255, 0, 0); @@ -47,6 +45,9 @@ bool Gradient::load_file(const std::filesystem::path& file_path) { if (error) return false; + // make sure the table starts at 0 + step(0, 0, 0, 0); + auto reader = FileLineReader(gradient_file); for (const auto& line : reader) { if (line.length() == 0 || line[0] == '#') @@ -73,17 +74,24 @@ bool Gradient::load_file(const std::filesystem::path& file_path) { } } + // extend the gradient from the current index to the end of the table + step(255, prev_r, prev_g, prev_b); + return true; } void Gradient::step(int16_t index, int16_t r, int16_t g, int16_t b) { - for (int16_t i = prev_index; i <= index; i++) { - float x = (float)(i - prev_index) / (index - prev_index); - float y = 1.0f - x; + // prevent division by 0 if index == prev_index + int16_t range = index - prev_index; + if (range == 0) range = 1; + + for (int16_t i = prev_index; i <= index; i++) { + int16_t t = i - prev_index; + + int16_t new_r = prev_r + (t * (r - prev_r) + range / 2) / range; + int16_t new_g = prev_g + (t * (g - prev_g) + range / 2) / range; + int16_t new_b = prev_b + (t * (b - prev_b) + range / 2) / range; - int16_t new_r = prev_r * y + r * x; - int16_t new_g = prev_g * y + g * x; - int16_t new_b = prev_b * y + b * x; if (i <= 255) lut[i] = ui::Color(new_r, new_g, new_b); } diff --git a/firmware/application/ui/ui_menu.cpp b/firmware/application/ui/ui_menu.cpp index 56ac405c5..98e2988bf 100644 --- a/firmware/application/ui/ui_menu.cpp +++ b/firmware/application/ui/ui_menu.cpp @@ -159,16 +159,15 @@ size_t MenuView::item_count() const { return menu_items.size(); } -void MenuView::add_item(MenuItem new_item) { - menu_items.push_back(new_item); +void MenuView::add_item(MenuItem&& new_item) { + menu_items.push_back(std::move(new_item)); update_items(); } void MenuView::add_items(std::initializer_list new_items) { - for (auto item : new_items) { - add_item(item); - } + menu_items.insert(menu_items.end(), new_items); + update_items(); } void MenuView::update_items() { diff --git a/firmware/application/ui/ui_menu.hpp b/firmware/application/ui/ui_menu.hpp index 2fc2b5be3..25597fcfc 100644 --- a/firmware/application/ui/ui_menu.hpp +++ b/firmware/application/ui/ui_menu.hpp @@ -83,7 +83,10 @@ class MenuView : public View { ~MenuView(); - void add_item(MenuItem new_item); + // This function takes a temporary to avoid copies and heap allocations. + // To pass a variable 'item', use add_item(std::move(item)), + // or construct the MenuItem in the call, add_item(MenuItem{...}) + void add_item(MenuItem&& new_item); void add_items(std::initializer_list new_items); void clear(); size_t item_count() const;