From 0a3aa706ef78d9df5e9da83bcdd5b3fbaff17d73 Mon Sep 17 00:00:00 2001 From: Kyle Reed <3761006+kallanreed@users.noreply.github.com> Date: Sat, 29 Jul 2023 15:36:00 -0700 Subject: [PATCH] Scanner cleanup (#1320) * FreqmanDB in Scanner * Format * Add comment on squelch(0) --- firmware/application/apps/ui_freqman.cpp | 6 +- firmware/application/apps/ui_freqman.hpp | 15 +- firmware/application/apps/ui_scanner.cpp | 364 ++++++++++------------- firmware/application/apps/ui_scanner.hpp | 65 ++-- 4 files changed, 212 insertions(+), 238 deletions(-) diff --git a/firmware/application/apps/ui_freqman.cpp b/firmware/application/apps/ui_freqman.cpp index f0a010e0..e8d12f16 100644 --- a/firmware/application/apps/ui_freqman.cpp +++ b/firmware/application/apps/ui_freqman.cpp @@ -487,7 +487,7 @@ void FrequencyEditView::populate_bandwidth_options() { if (entry_.modulation < std::size(freqman_bandwidths)) { auto& bandwidths = freqman_bandwidths[entry_.modulation]; - for (auto i = 1u; i < bandwidths.size(); ++i) { + for (auto i = 0u; i < bandwidths.size(); ++i) { auto& item = bandwidths[i]; options.push_back({item.first, (OptionsField::value_t)i}); } @@ -500,7 +500,7 @@ void FrequencyEditView::populate_step_options() { OptionsField::options_t options; options.push_back({"None", -1}); - for (auto i = 1u; i < freqman_steps.size(); ++i) { + for (auto i = 0u; i < freqman_steps.size(); ++i) { auto& item = freqman_steps[i]; options.push_back({item.first, (OptionsField::value_t)i}); } @@ -513,7 +513,7 @@ void FrequencyEditView::populate_tone_options() { OptionsField::options_t options; options.push_back({"None", -1}); - for (auto i = 1u; i < tone_keys.size(); ++i) { + for (auto i = 0u; i < tone_keys.size(); ++i) { auto& item = tone_keys[i]; options.push_back({fx100_string(item.second), (OptionsField::value_t)i}); } diff --git a/firmware/application/apps/ui_freqman.hpp b/firmware/application/apps/ui_freqman.hpp index 6f9ae453..3ab0c75d 100644 --- a/firmware/application/apps/ui_freqman.hpp +++ b/firmware/application/apps/ui_freqman.hpp @@ -219,12 +219,15 @@ class FrequencyEditView : public View { {{0 * 8, 10 * 16}, "Description:", Color::light_grey()}, }; - OptionsField field_type{{13 * 8, 3 * 16}, 8, { - {"Single", 0}, - {"Range", 1}, - {"HamRadio", 2}, - {"Raw", 3}, - }}; + OptionsField field_type{ + {13 * 8, 3 * 16}, + 8, + { + {"Single", 0}, + {"Range", 1}, + {"HamRadio", 2}, + {"Raw", 3}, + }}; FrequencyField field_freq_a{{13 * 8, 4 * 16}}; diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 7930ba96..d71abebb 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -21,20 +21,25 @@ */ #include "ui_scanner.hpp" + +#include "optional.hpp" #include "ui_fileman.hpp" #include "ui_freqman.hpp" using namespace portapack; +namespace fs = std::filesystem; namespace ui { +static const fs::path default_scan_file{u"FREQMAN/SCANNER.TXT"}; + ScannerThread::ScannerThread(std::vector frequency_list) : frequency_list_{std::move(frequency_list)} { _manual_search = false; create_thread(); } -ScannerThread::ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step_hz) +ScannerThread::ScannerThread(const scanner_range_t& frequency_range, size_t def_step_hz) : frequency_range_(frequency_range), def_step_hz_(def_step_hz) { _manual_search = true; create_thread(); @@ -80,7 +85,7 @@ void ScannerThread::set_freq_del(const rf::Frequency v) { } // Force a one-time forward or reverse frequency index change; OK to do this without pausing scan thread -//(used when rotary encoder is turned) +// (used when rotary encoder is turned) void ScannerThread::set_index_stepper(const int32_t v) { _index_stepper = v; } @@ -228,17 +233,26 @@ void ScannerView::handle_retune(int64_t freq, uint32_t freq_idx) { } if (!manual_search) { - if (frequency_list.size() > 0) { + if (entries.size() > 0) text_current_index.set(to_string_dec_uint(freq_idx + 1, 3)); - } - if (freq_idx < description_list.size() && description_list[freq_idx].size() > 1) - desc_current_index.set(description_list[freq_idx]); // Show description from file + if (freq_idx < entries.size() && entries[freq_idx].description.size() > 1) + text_current_desc.set(entries[freq_idx].description); // Show description from file else - desc_current_index.set(desc_freq_list_scan); // Show Scan file name (no description in file) + text_current_desc.set(loaded_filename()); // Show Scan file name (no description in file) } } +std::string ScannerView::loaded_filename() const { + auto filename = loaded_path.filename().string(); + if (filename.length() > 23) { // Truncate and add ellipses if long file name + filename.resize(22); + filename = filename + "+"; + } + + return filename; +} + void ScannerView::focus() { button_load.focus(); } @@ -254,46 +268,46 @@ ScannerView::~ScannerView() { void ScannerView::show_max_index() { // show total number of freqs to scan text_current_index.set("---"); - if (frequency_list.size() == FREQMAN_MAX_PER_FILE) { + if (entries.size() == FREQMAN_MAX_PER_FILE) { text_max_index.set_style(&Styles::red); text_max_index.set("/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE) + " (DB MAX!)"); } else { text_max_index.set_style(&Styles::grey); - text_max_index.set("/ " + to_string_dec_uint(frequency_list.size())); + text_max_index.set("/ " + to_string_dec_uint(entries.size())); } } ScannerView::ScannerView( NavigationView& nav) - : nav_{nav}, loaded_file_name{"SCANNER"} { - add_children({&labels, - &field_lna, - &field_vga, - &field_rf_amp, - &field_volume, - &field_bw, - &field_squelch, - &field_browse_wait, - &field_lock_wait, - &button_load, - &button_clear, - &rssi, - &text_current_index, - &text_max_index, - &desc_current_index, - &big_display, - &button_manual_start, - &button_manual_end, - &field_mode, - &field_step, - &button_manual_search, - &button_pause, - &button_dir, - &button_audio_app, - &button_mic_app, - &button_add, - &button_remove - + : nav_{nav} { + add_children({ + &labels, + &field_lna, + &field_vga, + &field_rf_amp, + &field_volume, + &field_bw, + &field_squelch, + &field_browse_wait, + &field_lock_wait, + &button_load, + &button_clear, + &rssi, + &text_current_index, + &text_max_index, + &text_current_desc, + &big_display, + &button_manual_start, + &button_manual_end, + &field_mode, + &field_step, + &button_manual_search, + &button_pause, + &button_dir, + &button_audio_app, + &button_mic_app, + &button_add, + &button_remove, }); // Populate option text for these fields @@ -312,14 +326,14 @@ ScannerView::ScannerView( frequency_range.max = stored_freq + 1000000; button_manual_end.set_text(to_string_short_freq(frequency_range.max)); - // Button to load txt files from the FREQMAN folder + // Button to load a Freqman file. button_load.on_select = [this, &nav](Button&) { auto open_view = nav.push(".TXT"); open_view->push_dir(freqman_dir); open_view->on_changed = [this, &nav](std::filesystem::path new_file_path) { if (new_file_path.native().find(freqman_dir.native()) == 0) { scan_pause(); - frequency_file_load(new_file_path.stem().string(), true); + frequency_file_load(new_file_path); } else { nav.display_modal("LOAD ERROR", "A valid file from\nFREQMAN directory is\nrequired."); } @@ -328,14 +342,13 @@ ScannerView::ScannerView( // Button to clear in-memory frequency list button_clear.on_select = [this, &nav](Button&) { - if (scan_thread && frequency_list.size()) { + if (scan_thread && entries.size()) { scan_thread->stop(); // STOP SCANNER THREAD - frequency_list.clear(); - description_list.clear(); + entries.clear(); show_max_index(); // UPDATE new list size on screen text_current_index.set(""); - desc_current_index.set(desc_freq_list_scan); + text_current_desc.set(loaded_filename()); scan_thread->set_freq_lock(0); // Reset the scanner lock // FUTURE: Consider switching to manual search mode automatically after clear (but would need to validate freq range) @@ -404,16 +417,15 @@ ScannerView::ScannerView( // Button to delete current frequency from scan Freq List button_remove.on_select = [this](Button&) { - if (scan_thread && (frequency_list.size() > current_index)) { + if (scan_thread && (entries.size() > current_index)) { scan_thread->set_scanning(false); // PAUSE Scanning if necessary - // Remove frequency from the Freq List in memory (it is not removed from the file) - scan_thread->set_freq_del(frequency_list[current_index]); - description_list.erase(description_list.begin() + current_index); - frequency_list.erase(frequency_list.begin() + current_index); + // Remove frequency from the Freq List in memory (it is not removed from the file). + scan_thread->set_freq_del(entries[current_index].freq); + entries.erase(entries.begin() + current_index); show_max_index(); // UPDATE new list size on screen - desc_current_index.set(""); // Clean up description (cosmetic detail) + text_current_desc.set(""); // Clean up description (cosmetic detail) scan_thread->set_freq_lock(0); // Reset the scanner lock } }; @@ -432,15 +444,7 @@ ScannerView::ScannerView( manual_search = false; // Switch to List Scan mode } - audio::output::stop(); - - if (scan_thread) - scan_thread->stop(); // STOP SCANNER THREAD - - if (userpause) // If user-paused, resume - user_resume(); - - start_scan_thread(); // RESTART SCANNER THREAD in selected mode + restart_scan(); }; // Mode field was changed (AM/NFM/WFM) @@ -467,17 +471,8 @@ ScannerView::ScannerView( field_step.on_change = [this](size_t, OptionsField::value_t v) { receiver_model.set_frequency_step(v); - if (manual_search && scan_thread) { - // Restart scan thread with new step value - scan_thread->stop(); // STOP SCANNER THREAD - - // Resuming pause automatically - // FUTURE: Consider whether we should stay in Pause mode... - if (userpause) // If user-paused, resume - user_resume(); - - start_scan_thread(); // RESTART SCANNER THREAD in Manual Search mode - } + if (manual_search && scan_thread) + restart_scan(); }; // Button to toggle Forward/Reverse @@ -491,68 +486,37 @@ ScannerView::ScannerView( bigdisplay_update(BDC_GREY); // Back to grey color }; - // TODO: remove this parsing? // Button to add current frequency (found during Search) to the Scan Frequency List button_add.on_select = [this](Button&) { - File scanner_file; - const std::string freq_file_path = "FREQMAN/" + loaded_file_name + ".TXT"; - auto result = scanner_file.open(freq_file_path); // First search if freq is already in txt + FreqmanDB db; + if (db.open(loaded_path, /*create*/ true)) { + freqman_entry entry{ + .frequency_a = current_frequency, + .type = freqman_type::Single, + }; - if (!result.is_valid()) { - const std::string frequency_to_add = "f=" + to_string_dec_uint(current_frequency / 1000) + to_string_dec_uint(current_frequency % 1000UL, 3, '0'); - - bool found = false; - constexpr size_t buffer_size = 1024; - char buffer[buffer_size]; - - for (size_t pointer = 0, freq_str_idx = 0; pointer < scanner_file.size(); pointer += buffer_size) { - size_t adjusted_buffer_size; - if (pointer + buffer_size >= scanner_file.size()) { - memset(buffer, 0, sizeof(buffer)); - adjusted_buffer_size = scanner_file.size() - pointer; - } else { - adjusted_buffer_size = buffer_size; - } - - scanner_file.seek(pointer); - scanner_file.read(buffer, adjusted_buffer_size); - - for (size_t i = 0; i < adjusted_buffer_size; ++i) { - if (buffer[i] == frequency_to_add.data()[freq_str_idx]) { - ++freq_str_idx; - if (freq_str_idx >= frequency_to_add.size()) { - found = true; - break; - } - } else { - freq_str_idx = 0; - } - } - - if (found) { - break; - } - } + // Look for existing entry with same frequency. + auto it = db.find_entry([&entry](const auto& e) { + return e.frequency_a == entry.frequency_a; + }); + auto found = (it != db.end()); if (found) { nav_.display_modal("Error", "Frequency already exists"); - bigdisplay_update(-1); // After showing an error + bigdisplay_update(-1); // Need to poke this control after displaying modal? } else { - scanner_file.append(freq_file_path); // Second: append if it is not there - scanner_file.write_line(frequency_to_add); - + db.append_entry(entry); // Add to frequency_list in memory too, since we can now switch back from manual mode - // Note that we are allowing freqs to be added to file (code above) that exceed the max count we can load into memory - if (frequency_list.size() < FREQMAN_MAX_PER_FILE) { - frequency_list.push_back(current_frequency); - description_list.push_back(""); - + // Note that we are allowing freqs to be added to file (code above) that exceed the + // max count we can load into memory. + if (entries.size() < FREQMAN_MAX_PER_FILE) { + entries.push_back({current_frequency, ""}); show_max_index(); // Display updated frequency list size } } } else { - nav_.display_modal("Error", "Cannot open " + loaded_file_name + ".TXT\nfor appending freq."); - bigdisplay_update(-1); // After showing an error + nav_.display_modal("Error", "Cannot open " + loaded_path.filename().string() + "\nfor appending freq."); + bigdisplay_update(-1); // Need to poke this control after displaying modal? } }; @@ -566,106 +530,76 @@ ScannerView::ScannerView( field_squelch.on_change = [this](int32_t v) { squelch = v; }; field_squelch.set_value(-30); - // LEARN FREQUENCIES - std::string scanner_txt = "SCANNER"; - frequency_file_load(scanner_txt); + // LOAD FREQUENCIES + frequency_file_load(default_scan_file); } -void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) { - bool found_range{false}; - bool found_single{false}; +void ScannerView::frequency_file_load(const fs::path& path) { freqman_index_t def_mod_index{freqman_invalid_index}; freqman_index_t def_bw_index{freqman_invalid_index}; freqman_index_t def_step_index{freqman_invalid_index}; - // stop everything running now if required - if (stop_all_before) { - scan_thread->stop(); - frequency_list.clear(); // clear the existing frequency list (expected behavior) - description_list.clear(); + FreqmanDB db; + if (!db.open(path)) { + text_current_desc.set("NO " + path.filename().string()); + loaded_path = default_scan_file; + return; } - if (load_freqman_file(file_name, database, {})) { - loaded_file_name = file_name; - for (auto& entry_ptr : database) { - if (frequency_list.size() >= FREQMAN_MAX_PER_FILE) + entries.clear(); + loaded_path = path; + Optional range; + + for (auto entry : db) { + if (is_invalid(def_mod_index)) + def_mod_index = entry.modulation; + + if (is_invalid(def_bw_index)) + def_bw_index = entry.bandwidth; + + if (is_invalid(def_step_index)) + def_step_index = entry.step; + + switch (entry.type) { + case freqman_type::Single: + entries.push_back({entry.frequency_a, entry.description}); + break; + case freqman_type::HamRadio: + entries.push_back({entry.frequency_a, "R: " + entry.description}); + entries.push_back({entry.frequency_b, "T: " + entry.description}); + break; + case freqman_type::Range: + // NB: Only the first range will be loaded. + if (!range) + range = {entry.frequency_a, entry.frequency_b}; + break; + default: break; - - auto& entry = *entry_ptr; - - // Get modulation & bw & step from file if specified - // Note these values could be different for each line in the file, but we only look at the first one - // - // Note that freqman requires a very specific string for these parameters, - // so check syntax in frequency file if specified value isn't being loaded - // - if (is_invalid(def_mod_index)) - def_mod_index = entry.modulation; - - if (is_invalid(def_bw_index)) - def_bw_index = entry.bandwidth; - - if (is_invalid(def_step_index)) - def_step_index = entry.step; - - // Get frequency - if (entry.type == freqman_type::Range) { - if (!found_range) { - // Set Start & End Search Range instead of populating the small in-memory frequency table - // NOTE: There may be multiple single frequencies in file, but only one search range is supported. - found_range = true; - frequency_range.min = entry.frequency_a; - button_manual_start.set_text(to_string_short_freq(frequency_range.min)); - frequency_range.max = entry.frequency_b; - button_manual_end.set_text(to_string_short_freq(frequency_range.max)); - } - } else if (entry.type == freqman_type::Single) { - found_single = true; - frequency_list.push_back(entry.frequency_a); - description_list.push_back(entry.description); - } else if (entry.type == freqman_type::HamRadio) { - // For HAM repeaters, add both receive & transmit frequencies to scan list and modify description - // (FUTURE fw versions might handle these differently) - found_single = true; - frequency_list.push_back(entry.frequency_a); - description_list.push_back("R:" + entry.description); - - if ((entry.frequency_a != entry.frequency_b) && - (frequency_list.size() < FREQMAN_MAX_PER_FILE)) { - frequency_list.push_back(entry.frequency_b); - description_list.push_back("T:" + entry.description); - } - } } - } else { - loaded_file_name = "SCANNER"; // back to the default frequency file - desc_current_index.set(" NO " + file_name + ".TXT FILE ..."); - } - desc_freq_list_scan = loaded_file_name + ".TXT"; - if (desc_freq_list_scan.length() > 23) { // Truncate description and add ellipses if long file name - desc_freq_list_scan.resize(20); - desc_freq_list_scan = desc_freq_list_scan + "..."; + if (entries.size() >= FREQMAN_MAX_PER_FILE) + break; } if (is_valid(def_mod_index) && def_mod_index != (freqman_index_t)field_mode.selected_index_value()) - field_mode.set_by_value(def_mod_index); // Update mode (also triggers a change callback that disables & reenables RF background) + field_mode.set_by_value(def_mod_index); - if (is_valid(def_bw_index)) // Update BW if specified in file + if (is_valid(def_bw_index)) field_bw.set_selected_index(def_bw_index); - if (is_valid(def_step_index)) // Update step if specified in file + if (is_valid(def_step_index)) field_step.set_selected_index(def_step_index); - audio::output::stop(); + // Found range, set it and update UI. + if (range) { + frequency_range = *range; + button_manual_start.set_text(to_string_short_freq(frequency_range.min)); + button_manual_end.set_text(to_string_short_freq(frequency_range.max)); + } - if (userpause) // If user-paused, resume - user_resume(); - - // Scan list if we found one, otherwise do manual range search - manual_search = !found_single; - - start_scan_thread(); + // Scan entries if any, otherwise do manual range search. + manual_search = entries.empty(); + restart_scan(); } void ScannerView::update_squelch_while_paused(int32_t max_db) { @@ -754,7 +688,8 @@ void ScannerView::user_resume() { userpause = false; // Resume scanning } -void ScannerView::change_mode(freqman_index_t new_mod) { // Before this, do a scan_thread->stop(); After this do a start_scan_thread() +// Before this, do a scan_thread->stop(); After this do a start_scan_thread() +void ScannerView::change_mode(freqman_index_t new_mod) { using option_t = std::pair; using options_t = std::vector; options_t bw; @@ -791,22 +726,41 @@ void ScannerView::change_mode(freqman_index_t new_mod) { // Before this, do a s void ScannerView::start_scan_thread() { receiver_model.enable(); + // Disable squelch on the model because RSSI handler is where the + // actual squelching is applied for this app. receiver_model.set_squelch_level(0); show_max_index(); // Start Scanner Thread - // FUTURE: Consider passing additional control flags (fwd,userpause,etc) to scanner thread at start (perhaps in a data structure) if (manual_search) { button_manual_search.set_text("SCAN"); // Update meaning of Manual Scan button - desc_current_index.set(desc_freq_range_search); + text_current_desc.set("SEARCHING..."); scan_thread = std::make_unique(frequency_range, field_step.selected_index_value()); } else { button_manual_search.set_text("SRCH"); // Update meaning of Manual Scan button - desc_current_index.set(desc_freq_list_scan); - scan_thread = std::make_unique(frequency_list); + text_current_desc.set(loaded_filename()); + + // TODO: just pass ref to the thread? + std::vector frequency_list; + frequency_list.reserve(entries.size()); + for (const auto& entry : entries) + frequency_list.push_back(entry.freq); + + scan_thread = std::make_unique(std::move(frequency_list)); } scan_thread->set_scanning_direction(fwd); } +void ScannerView::restart_scan() { + audio::output::stop(); + if (scan_thread) // STOP SCANNER THREAD + scan_thread->stop(); + + if (userpause) // If user-paused, resume + user_resume(); + + start_scan_thread(); // RESTART SCANNER THREAD in selected mode +} + } /* namespace ui */ diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp index 21ddf989..0cad2313 100644 --- a/firmware/application/apps/ui_scanner.hpp +++ b/firmware/application/apps/ui_scanner.hpp @@ -20,19 +20,20 @@ * Boston, MA 02110-1301, USA. */ -#include "ui.hpp" -#include "receiver_model.hpp" +#include "audio.hpp" +#include "analog_audio_app.hpp" +#include "baseband_api.hpp" +#include "file.hpp" +#include "freqman.hpp" +#include "freqman_db.hpp" +#include "portapack_persistent_memory.hpp" #include "radio_state.hpp" +#include "receiver_model.hpp" +#include "string_format.hpp" +#include "ui.hpp" +#include "ui_mictx.hpp" #include "ui_receiver.hpp" #include "ui_styles.hpp" -#include "freqman.hpp" -#include "analog_audio_app.hpp" -#include "audio.hpp" -#include "ui_mictx.hpp" -#include "portapack_persistent_memory.hpp" -#include "baseband_api.hpp" -#include "string_format.hpp" -#include "file.hpp" #define SCANNER_SLEEP_MS 50 // ms that Scanner Thread sleeps per loop #define STATISTICS_UPDATES_PER_SEC 10 @@ -40,10 +41,28 @@ namespace ui { +// TODO: There is too much duplicated data in these classes. +// ScannerThread should just use more from the View. +// Or perhaps ScannerThread should just be in the View. + +// TODO: Too many functions mix work and UI update. +// Consolidate UI fixup to a single function. + +// TODO: Just use freqman_entry. +struct scanner_entry_t { + rf::Frequency freq; + std::string description; +}; + +struct scanner_range_t { + int64_t min; + int64_t max; +}; + class ScannerThread { public: ScannerThread(std::vector frequency_list); - ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step_hz); + ScannerThread(const scanner_range_t& frequency_range, size_t def_step_hz); ~ScannerThread(); void set_scanning(const bool v); @@ -65,7 +84,7 @@ class ScannerThread { private: std::vector frequency_list_{}; - jammer::jammer_range_t frequency_range_{false, 0, 0}; + scanner_range_t frequency_range_{0, 0}; size_t def_step_hz_{0}; Thread* thread{nullptr}; @@ -89,10 +108,6 @@ class ScannerView : public View { void focus() override; std::string title() const override { return "Scanner"; }; - std::vector frequency_list{}; - std::vector description_list{}; - - // void set_parent_rect(const Rect new_parent_rect) override; private: app_settings::SettingsManager settings_{ @@ -102,18 +117,21 @@ class ScannerView : public View { RxRadioState radio_state_{}; void start_scan_thread(); + void restart_scan(); void change_mode(freqman_index_t mod_type); void show_max_index(); void scan_pause(); void scan_resume(); void user_resume(); - void frequency_file_load(std::string file_name, bool stop_all_before = false); + void frequency_file_load(const std::filesystem::path& path); void bigdisplay_update(int32_t); void update_squelch_while_paused(int32_t max_db); void on_statistics_update(const ChannelStatistics& statistics); void handle_retune(int64_t freq, uint32_t freq_idx); - jammer::jammer_range_t frequency_range{false, 0, 0}; // perfect for manual scan task too... + std::string loaded_filename() const; + + scanner_range_t frequency_range{0, 0}; int32_t squelch{0}; uint32_t browse_timer{0}; uint32_t lock_timer{0}; @@ -122,10 +140,12 @@ class ScannerView : public View { rf::Frequency bigdisplay_current_frequency{0}; uint32_t browse_wait{0}; uint32_t lock_wait{0}; - freqman_db database{}; - std::string loaded_file_name; + + std::filesystem::path loaded_path{}; + std::vector entries{}; uint32_t current_index{0}; rf::Frequency current_frequency{0}; + bool userpause{false}; bool manual_search{false}; bool fwd{true}; // to preserve direction setting even if scan_thread restarted @@ -137,9 +157,6 @@ class ScannerView : public View { BDC_RED }; - std::string desc_freq_range_search = "SEARCHING..."; - std::string desc_freq_list_scan = ""; - Labels labels{ {{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL:", Color::light_grey()}, {{0 * 8, 1 * 16}, "BW: SQ: Wsa: Wsl:", Color::light_grey()}, @@ -204,7 +221,7 @@ class ScannerView : public View { {4 * 8, 3 * 16, 18 * 8, 16}, }; - Text desc_current_index{ + Text text_current_desc{ {0, 4 * 16, 240 - 6 * 8, 16}, };