mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Scanner persisted freq file, TextField for current item (#1403)
* Don't truncate string passed to Text widget * Focus TextField on touch like other fields * TextField for current, save last opened freq file
This commit is contained in:
parent
4a1479957c
commit
f537c7896e
@ -31,8 +31,6 @@ namespace fs = std::filesystem;
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
static const fs::path default_scan_file{u"FREQMAN/SCANNER.TXT"};
|
|
||||||
|
|
||||||
ScannerThread::ScannerThread(std::vector<rf::Frequency> frequency_list)
|
ScannerThread::ScannerThread(std::vector<rf::Frequency> frequency_list)
|
||||||
: frequency_list_{std::move(frequency_list)} {
|
: frequency_list_{std::move(frequency_list)} {
|
||||||
_manual_search = false;
|
_manual_search = false;
|
||||||
@ -234,7 +232,7 @@ void ScannerView::handle_retune(int64_t freq, uint32_t freq_idx) {
|
|||||||
|
|
||||||
if (!manual_search) {
|
if (!manual_search) {
|
||||||
if (entries.size() > 0)
|
if (entries.size() > 0)
|
||||||
text_current_index.set(to_string_dec_uint(freq_idx + 1, 3));
|
field_current_index.set_text(to_string_dec_uint(freq_idx + 1, 3));
|
||||||
|
|
||||||
if (freq_idx < entries.size() && entries[freq_idx].description.size() > 1)
|
if (freq_idx < entries.size() && entries[freq_idx].description.size() > 1)
|
||||||
text_current_desc.set(entries[freq_idx].description); // Show description from file
|
text_current_desc.set(entries[freq_idx].description); // Show description from file
|
||||||
@ -243,9 +241,20 @@ void ScannerView::handle_retune(int64_t freq, uint32_t freq_idx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScannerView::handle_encoder(EncoderEvent delta) {
|
||||||
|
auto index_step = delta > 0 ? 1 : -1;
|
||||||
|
|
||||||
|
if (scan_thread)
|
||||||
|
scan_thread->set_index_stepper(index_step);
|
||||||
|
|
||||||
|
// Restart browse timer when frequency changes.
|
||||||
|
if (browse_timer != 0)
|
||||||
|
browse_timer = 1;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ScannerView::loaded_filename() const {
|
std::string ScannerView::loaded_filename() const {
|
||||||
auto filename = loaded_path.filename().string();
|
auto filename = freqman_file;
|
||||||
if (filename.length() > 23) { // Truncate and add ellipses if long file name
|
if (filename.length() > 23) { // Truncate long file name.
|
||||||
filename.resize(22);
|
filename.resize(22);
|
||||||
filename = filename + "+";
|
filename = filename + "+";
|
||||||
}
|
}
|
||||||
@ -266,7 +275,7 @@ ScannerView::~ScannerView() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScannerView::show_max_index() { // show total number of freqs to scan
|
void ScannerView::show_max_index() { // show total number of freqs to scan
|
||||||
text_current_index.set("---");
|
field_current_index.set_text("---");
|
||||||
|
|
||||||
if (entries.size() == FREQMAN_MAX_PER_FILE) {
|
if (entries.size() == FREQMAN_MAX_PER_FILE) {
|
||||||
text_max_index.set_style(&Styles::red);
|
text_max_index.set_style(&Styles::red);
|
||||||
@ -293,7 +302,7 @@ ScannerView::ScannerView(
|
|||||||
&button_load,
|
&button_load,
|
||||||
&button_clear,
|
&button_clear,
|
||||||
&rssi,
|
&rssi,
|
||||||
&text_current_index,
|
&field_current_index,
|
||||||
&text_max_index,
|
&text_max_index,
|
||||||
&text_current_desc,
|
&text_current_desc,
|
||||||
&big_display,
|
&big_display,
|
||||||
@ -336,14 +345,14 @@ ScannerView::ScannerView(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button to clear in-memory frequency list
|
// Button to clear in-memory frequency list.
|
||||||
button_clear.on_select = [this, &nav](Button&) {
|
button_clear.on_select = [this, &nav](Button&) {
|
||||||
if (scan_thread && entries.size()) {
|
if (scan_thread && entries.size()) {
|
||||||
scan_thread->stop(); // STOP SCANNER THREAD
|
scan_thread->stop(); // STOP SCANNER THREAD
|
||||||
entries.clear();
|
entries.clear();
|
||||||
|
|
||||||
show_max_index(); // UPDATE new list size on screen
|
show_max_index(); // UPDATE new list size on screen
|
||||||
text_current_index.set("");
|
field_current_index.set_text("");
|
||||||
text_current_desc.set(loaded_filename());
|
text_current_desc.set(loaded_filename());
|
||||||
scan_thread->set_freq_lock(0); // Reset the scanner lock
|
scan_thread->set_freq_lock(0); // Reset the scanner lock
|
||||||
|
|
||||||
@ -351,7 +360,7 @@ ScannerView::ScannerView(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button to configure starting frequency for a manual range search
|
// Button to configure starting frequency for a manual range search.
|
||||||
button_manual_start.on_select = [this, &nav](Button& button) {
|
button_manual_start.on_select = [this, &nav](Button& button) {
|
||||||
auto new_view = nav_.push<FrequencyKeypadView>(frequency_range.min);
|
auto new_view = nav_.push<FrequencyKeypadView>(frequency_range.min);
|
||||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||||
@ -360,7 +369,7 @@ ScannerView::ScannerView(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button to configure ending frequency for a manual range search
|
// Button to configure ending frequency for a manual range search.
|
||||||
button_manual_end.on_select = [this, &nav](Button& button) {
|
button_manual_end.on_select = [this, &nav](Button& button) {
|
||||||
auto new_view = nav.push<FrequencyKeypadView>(frequency_range.max);
|
auto new_view = nav.push<FrequencyKeypadView>(frequency_range.max);
|
||||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||||
@ -369,7 +378,7 @@ ScannerView::ScannerView(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button to pause/resume scan (note that some other buttons will trigger resume also)
|
// Button to pause/resume scan (note that some other buttons will trigger resume also).
|
||||||
button_pause.on_select = [this](ButtonWithEncoder&) {
|
button_pause.on_select = [this](ButtonWithEncoder&) {
|
||||||
if (userpause)
|
if (userpause)
|
||||||
user_resume();
|
user_resume();
|
||||||
@ -380,19 +389,14 @@ ScannerView::ScannerView(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encoder dial causes frequency change when focus is on pause button
|
// Encoder dial causes frequency change when focus is on pause button or current index.
|
||||||
button_pause.on_change = [this]() {
|
button_pause.on_change = [this]() {
|
||||||
int32_t encoder_delta{(button_pause.get_encoder_delta() > 0) ? 1 : -1};
|
handle_encoder(button_pause.get_encoder_delta());
|
||||||
|
|
||||||
if (scan_thread)
|
|
||||||
scan_thread->set_index_stepper(encoder_delta);
|
|
||||||
|
|
||||||
// Restart browse timer when frequency changes
|
|
||||||
if (browse_timer != 0)
|
|
||||||
browse_timer = 1;
|
|
||||||
|
|
||||||
button_pause.set_encoder_delta(0);
|
button_pause.set_encoder_delta(0);
|
||||||
};
|
};
|
||||||
|
field_current_index.on_encoder_change = [this](TextField&, EncoderEvent delta) {
|
||||||
|
handle_encoder(delta);
|
||||||
|
};
|
||||||
|
|
||||||
// Button to switch to Audio app
|
// Button to switch to Audio app
|
||||||
button_audio_app.on_select = [this](Button&) {
|
button_audio_app.on_select = [this](Button&) {
|
||||||
@ -485,7 +489,7 @@ ScannerView::ScannerView(
|
|||||||
// Button to add current frequency (found during Search) to the Scan Frequency List
|
// Button to add current frequency (found during Search) to the Scan Frequency List
|
||||||
button_add.on_select = [this](Button&) {
|
button_add.on_select = [this](Button&) {
|
||||||
FreqmanDB db;
|
FreqmanDB db;
|
||||||
if (db.open(loaded_path, /*create*/ true)) {
|
if (db.open(get_freqman_path(freqman_file), /*create*/ true)) {
|
||||||
freqman_entry entry{
|
freqman_entry entry{
|
||||||
.frequency_a = current_frequency,
|
.frequency_a = current_frequency,
|
||||||
.type = freqman_type::Single,
|
.type = freqman_type::Single,
|
||||||
@ -511,7 +515,7 @@ ScannerView::ScannerView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nav_.display_modal("Error", "Cannot open " + loaded_path.filename().string() + "\nfor appending freq.");
|
nav_.display_modal("Error", "Cannot open " + freqman_file + ".TXT\nfor appending freq.");
|
||||||
bigdisplay_update(-1); // Need to poke this control after displaying modal?
|
bigdisplay_update(-1); // Need to poke this control after displaying modal?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -531,7 +535,7 @@ ScannerView::ScannerView(
|
|||||||
receiver_model.set_squelch_level(0);
|
receiver_model.set_squelch_level(0);
|
||||||
|
|
||||||
// LOAD FREQUENCIES
|
// LOAD FREQUENCIES
|
||||||
frequency_file_load(default_scan_file);
|
frequency_file_load(get_freqman_path(freqman_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScannerView::frequency_file_load(const fs::path& path) {
|
void ScannerView::frequency_file_load(const fs::path& path) {
|
||||||
@ -542,12 +546,11 @@ void ScannerView::frequency_file_load(const fs::path& path) {
|
|||||||
FreqmanDB db;
|
FreqmanDB db;
|
||||||
if (!db.open(path)) {
|
if (!db.open(path)) {
|
||||||
text_current_desc.set("NO " + path.filename().string());
|
text_current_desc.set("NO " + path.filename().string());
|
||||||
loaded_path = default_scan_file;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.clear();
|
entries.clear();
|
||||||
loaded_path = path;
|
freqman_file = path.stem().string();
|
||||||
Optional<scanner_range_t> range;
|
Optional<scanner_range_t> range;
|
||||||
|
|
||||||
for (auto entry : db) {
|
for (auto entry : db) {
|
||||||
|
@ -110,6 +110,8 @@ class ScannerView : public View {
|
|||||||
std::string title() const override { return "Scanner"; };
|
std::string title() const override { return "Scanner"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr const char* default_freqman_file = "SCANNER";
|
||||||
|
|
||||||
RxRadioState radio_state_{};
|
RxRadioState radio_state_{};
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
@ -117,6 +119,7 @@ class ScannerView : public View {
|
|||||||
uint32_t lock_wait{2};
|
uint32_t lock_wait{2};
|
||||||
int32_t squelch{-30};
|
int32_t squelch{-30};
|
||||||
scanner_range_t frequency_range{0, MAX_UFREQ};
|
scanner_range_t frequency_range{0, MAX_UFREQ};
|
||||||
|
std::string freqman_file{default_freqman_file};
|
||||||
app_settings::SettingsManager settings_{
|
app_settings::SettingsManager settings_{
|
||||||
"rx_scanner"sv,
|
"rx_scanner"sv,
|
||||||
app_settings::Mode::RX,
|
app_settings::Mode::RX,
|
||||||
@ -126,6 +129,7 @@ class ScannerView : public View {
|
|||||||
{"scanner_squelch"sv, &squelch},
|
{"scanner_squelch"sv, &squelch},
|
||||||
{"range_min"sv, &frequency_range.min},
|
{"range_min"sv, &frequency_range.min},
|
||||||
{"range_max"sv, &frequency_range.max},
|
{"range_max"sv, &frequency_range.max},
|
||||||
|
{"file"sv, &freqman_file},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
@ -142,7 +146,7 @@ class ScannerView : public View {
|
|||||||
void update_squelch_while_paused(int32_t max_db);
|
void update_squelch_while_paused(int32_t max_db);
|
||||||
void on_statistics_update(const ChannelStatistics& statistics);
|
void on_statistics_update(const ChannelStatistics& statistics);
|
||||||
void handle_retune(int64_t freq, uint32_t freq_idx);
|
void handle_retune(int64_t freq, uint32_t freq_idx);
|
||||||
|
void handle_encoder(EncoderEvent delta);
|
||||||
std::string loaded_filename() const;
|
std::string loaded_filename() const;
|
||||||
|
|
||||||
uint32_t browse_timer{0};
|
uint32_t browse_timer{0};
|
||||||
@ -151,7 +155,6 @@ class ScannerView : public View {
|
|||||||
int32_t bigdisplay_current_color{-2};
|
int32_t bigdisplay_current_color{-2};
|
||||||
rf::Frequency bigdisplay_current_frequency{0};
|
rf::Frequency bigdisplay_current_frequency{0};
|
||||||
|
|
||||||
std::filesystem::path loaded_path{};
|
|
||||||
std::vector<scanner_entry_t> entries{};
|
std::vector<scanner_entry_t> entries{};
|
||||||
uint32_t current_index{0};
|
uint32_t current_index{0};
|
||||||
rf::Frequency current_frequency{0};
|
rf::Frequency current_frequency{0};
|
||||||
@ -223,8 +226,9 @@ class ScannerView : public View {
|
|||||||
{0 * 16, 2 * 16, 15 * 16, 8},
|
{0 * 16, 2 * 16, 15 * 16, 8},
|
||||||
};
|
};
|
||||||
|
|
||||||
Text text_current_index{
|
TextField field_current_index{
|
||||||
{0, 3 * 16, 3 * 8, 16},
|
{0, 3 * 16, 3 * 8, 16},
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
Text text_max_index{
|
Text text_max_index{
|
||||||
@ -235,9 +239,9 @@ class ScannerView : public View {
|
|||||||
{0, 4 * 16, 240 - 6 * 8, 16},
|
{0, 4 * 16, 240 - 6 * 8, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
BigFrequency big_display{// Show frequency in glamour
|
BigFrequency big_display{
|
||||||
{4, 6 * 16, 28 * 8, 52},
|
{4, 6 * 16, 28 * 8, 52},
|
||||||
0};
|
0};
|
||||||
|
|
||||||
Button button_manual_start{
|
Button button_manual_start{
|
||||||
{0 * 8, 11 * 16, 11 * 8, 28},
|
{0 * 8, 11 * 16, 11 * 8, 28},
|
||||||
|
@ -366,16 +366,17 @@ void Text::paint(Painter& painter) {
|
|||||||
const auto rect = screen_rect();
|
const auto rect = screen_rect();
|
||||||
auto s = has_focus() ? style().invert() : style();
|
auto s = has_focus() ? style().invert() : style();
|
||||||
auto max_len = (unsigned)rect.width() / s.font.char_width();
|
auto max_len = (unsigned)rect.width() / s.font.char_width();
|
||||||
|
auto text_view = std::string_view{text};
|
||||||
|
|
||||||
painter.fill_rectangle(rect, s.background);
|
painter.fill_rectangle(rect, s.background);
|
||||||
|
|
||||||
if (text.length() > max_len)
|
if (text_view.length() > max_len)
|
||||||
text.resize(max_len);
|
text_view = text_view.substr(0, max_len);
|
||||||
|
|
||||||
painter.draw_string(
|
painter.draw_string(
|
||||||
rect.location(),
|
rect.location(),
|
||||||
s,
|
s,
|
||||||
text);
|
text_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Labels ****************************************************************/
|
/* Labels ****************************************************************/
|
||||||
@ -1773,6 +1774,15 @@ bool TextField::on_encoder(EncoderEvent delta) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextField::on_touch(TouchEvent event) {
|
||||||
|
if (event.type == TouchEvent::Type::Start) {
|
||||||
|
focus();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* NumberField ***********************************************************/
|
/* NumberField ***********************************************************/
|
||||||
|
|
||||||
NumberField::NumberField(
|
NumberField::NumberField(
|
||||||
|
@ -208,6 +208,10 @@ class Text : public Widget {
|
|||||||
void paint(Painter& painter) override;
|
void paint(Painter& painter) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// NB: Don't truncate this string. The UI will only render
|
||||||
|
// as many characters as will fit in its rectange.
|
||||||
|
// Apps expect to be able to retrieve this string to avoid
|
||||||
|
// needing to hold additional copies in memory.
|
||||||
std::string text;
|
std::string text;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -703,6 +707,7 @@ class TextField : public Text {
|
|||||||
|
|
||||||
bool on_key(KeyEvent key) override;
|
bool on_key(KeyEvent key) override;
|
||||||
bool on_encoder(EncoderEvent delta) override;
|
bool on_encoder(EncoderEvent delta) override;
|
||||||
|
bool on_touch(TouchEvent event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Text::set;
|
using Text::set;
|
||||||
|
Loading…
Reference in New Issue
Block a user