mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 06:49:24 -05:00
Added range file and range type to frequency manager (mainly for jammer)
Made MenuView use less widgets, hopefully preventing crashes with large lists Fixed M10 sonde crash on packet receive Updated about screen Updated binary
This commit is contained in:
parent
b38adf3769
commit
3d2dacaf29
@ -42,8 +42,9 @@ bool load_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
char * line_start;
|
||||
char * line_end;
|
||||
std::string description;
|
||||
rf::Frequency value;
|
||||
rf::Frequency frequency_a, frequency_b;
|
||||
char file_data[256];
|
||||
freqman_entry_type type;
|
||||
|
||||
db.entries.clear();
|
||||
|
||||
@ -63,18 +64,34 @@ bool load_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
|
||||
line_start = file_data;
|
||||
|
||||
pos = strstr(file_data, "f=");
|
||||
if (!pos) break;
|
||||
if (!strstr(file_data, "f=") && !strstr(file_data, "a="))
|
||||
break;
|
||||
|
||||
// Look for complete lines in buffer
|
||||
while ((line_end = strstr(line_start, "\x0A"))) {
|
||||
// Read frequency
|
||||
pos = strstr(line_start, "f=");
|
||||
frequency_b = 0;
|
||||
type = SINGLE;
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
value = strtoll(pos, nullptr, 10);
|
||||
frequency_a = strtoll(pos, nullptr, 10);
|
||||
} else {
|
||||
// ...or range
|
||||
pos = strstr(line_start, "a=");
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
frequency_a = strtoll(pos, nullptr, 10);
|
||||
type = RANGE;
|
||||
pos = strstr(line_start, "b=");
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
frequency_b = strtoll(pos, nullptr, 10);
|
||||
} else
|
||||
value = 0;
|
||||
frequency_b = 0;
|
||||
} else
|
||||
frequency_a = 0;
|
||||
}
|
||||
|
||||
// Read description until , or LF
|
||||
pos = strstr(line_start, "d=");
|
||||
@ -85,7 +102,7 @@ bool load_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
} else
|
||||
description = "-";
|
||||
|
||||
db.entries.push_back({ value, "", description });
|
||||
db.entries.push_back({ frequency_a, frequency_b, description, type });
|
||||
n++;
|
||||
|
||||
if (n >= FREQMAN_MAX_PER_FILE) return true;
|
||||
@ -105,17 +122,33 @@ bool load_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
bool save_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
File freqman_file;
|
||||
std::string item_string;
|
||||
rf::Frequency f;
|
||||
rf::Frequency frequency_a, frequency_b;
|
||||
|
||||
if (!create_freqman_file(file_stem, freqman_file))
|
||||
return false;
|
||||
|
||||
for (size_t n = 0; n < db.entries.size(); n++) {
|
||||
f = db.entries[n].value;
|
||||
item_string = "f=" + to_string_dec_uint(f / 1000) + to_string_dec_uint(f % 1000UL, 3, '0'); // Please forgive me
|
||||
auto& entry = db.entries[n];
|
||||
|
||||
if (db.entries[n].description.size())
|
||||
item_string += ",d=" + db.entries[n].description;
|
||||
frequency_a = entry.frequency_a;
|
||||
|
||||
if (entry.type == SINGLE) {
|
||||
// Single
|
||||
|
||||
// TODO: Make to_string_dec_uint be able to return uint64_t's
|
||||
// Please forgive me...
|
||||
item_string = "f=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
|
||||
|
||||
} else {
|
||||
// Range
|
||||
frequency_b = entry.frequency_b;
|
||||
|
||||
item_string = "a=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
|
||||
item_string += ",b=" + to_string_dec_uint(frequency_b / 1000) + to_string_dec_uint(frequency_b % 1000UL, 3, '0');
|
||||
}
|
||||
|
||||
if (entry.description.size())
|
||||
item_string += ",d=" + entry.description;
|
||||
|
||||
freqman_file.write_line(item_string);
|
||||
}
|
||||
@ -132,16 +165,15 @@ bool create_freqman_file(std::string& file_stem, File& freqman_file) {
|
||||
}
|
||||
|
||||
std::string freqman_item_string(freqman_entry &entry, size_t max_length) {
|
||||
std::string item_string, frequency_str, description;
|
||||
rf::Frequency value;
|
||||
std::string item_string;
|
||||
|
||||
value = entry.value;
|
||||
entry.frequency_str = to_string_dec_int(value / 1000000, 4) + "." +
|
||||
to_string_dec_int((value / 100) % 10000, 4, '0');
|
||||
if (entry.type == SINGLE) {
|
||||
item_string = to_string_short_freq(entry.frequency_a) + "M: " + entry.description;
|
||||
} else {
|
||||
item_string = "Range: " + entry.description;
|
||||
}
|
||||
|
||||
item_string = entry.frequency_str + "M: " + entry.description;
|
||||
|
||||
if (entry.description.size() > max_length)
|
||||
if (item_string.size() > max_length)
|
||||
return item_string.substr(0, max_length - 3) + "...";
|
||||
|
||||
return item_string;
|
||||
|
@ -43,10 +43,16 @@ enum freqman_error {
|
||||
ERROR_DUPLICATE
|
||||
};
|
||||
|
||||
enum freqman_entry_type {
|
||||
SINGLE = 0,
|
||||
RANGE
|
||||
};
|
||||
|
||||
struct freqman_entry {
|
||||
rf::Frequency value { 0 };
|
||||
std::string frequency_str { };
|
||||
rf::Frequency frequency_a { 0 };
|
||||
rf::Frequency frequency_b { 0 };
|
||||
std::string description { };
|
||||
freqman_entry_type type { };
|
||||
};
|
||||
|
||||
struct freqman_db {
|
||||
|
@ -33,6 +33,7 @@
|
||||
//BUG: SCANNER Multiple slices
|
||||
|
||||
//TODO: Display file creation/modification date in FileLoadView
|
||||
//TODO: Super simple text file viewer
|
||||
//TODO: Display recording frequency in Replay (from associated .txt file, if present)
|
||||
//TODO: Clean up ReplayThread
|
||||
//TODO: Cap Wav viewer position
|
||||
@ -40,7 +41,6 @@
|
||||
//TODO: Use unit_auto_scale
|
||||
//TODO: Remove make_bistream from encoders.cpp, too complex, stinks. bitstream_append should be enough.
|
||||
//TODO: Continue work on proc_afskrx_corr, see python script (it works !)
|
||||
//TODO: Super simple text file viewer
|
||||
//TODO: De bruijn sequence scanner for encoders
|
||||
//TODO: FILEMAN Rename folders
|
||||
//TODO: FILEMAN Move files
|
||||
|
@ -82,7 +82,7 @@ void AboutView::update() {
|
||||
std::array<Color, 240> pixel_row;
|
||||
|
||||
slow_down++;
|
||||
if (slow_down & 1) return;
|
||||
if (slow_down % 3 < 2) return;
|
||||
|
||||
if (!timer) {
|
||||
if (loop) {
|
||||
|
@ -72,7 +72,7 @@ private:
|
||||
int32_t delay;
|
||||
} credits_t;
|
||||
|
||||
const credits_t credits[24] = {
|
||||
const credits_t credits[25] = {
|
||||
// 012345678901234567890123456789
|
||||
{ 60, "PortaPack|HAVOC", 0 },
|
||||
{ 7 * 8, "Git hash " GIT_REVISION, 16 },
|
||||
@ -90,12 +90,13 @@ private:
|
||||
{ 0 * 8, "TouchTunes infos Notpike", 16 },
|
||||
{ 4 * 8, "Subaru infos Tom", 0 },
|
||||
{ 18 * 8, "Wimmenhove", 24 },
|
||||
{ 12 * 8, "Thanks", 16 },
|
||||
{ 6 * 8, "Thanks & donators", 16 },
|
||||
{ 1 * 8, "Rainer Matla Keld Norman", 0 },
|
||||
{ 1 * 8, " Giorgio C. DC1RDB", 0 },
|
||||
{ 1 * 8, " Sigmounte Waax", 0 },
|
||||
{ 1 * 8, " Windyoona Channels", 0 },
|
||||
{ 1 * 8, " F4GEV", 24 },
|
||||
{ 1 * 8, " F4GEV Pyr3x", 0 },
|
||||
{ 1 * 8, " HB3YOE", 24 },
|
||||
{ 12 * 8, "MMXVII", -1 }
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,7 @@ std::filesystem::path FileManBaseView::get_selected_path() {
|
||||
|
||||
if (selected_path_str.back() != '/')
|
||||
selected_path_str += '/';
|
||||
selected_path_str += (entry_list[menu_view.highlighted()].entry_path.string());
|
||||
selected_path_str += (entry_list[menu_view.highlighted_index()].entry_path.string());
|
||||
|
||||
return selected_path_str;
|
||||
}
|
||||
@ -225,13 +225,13 @@ FileLoadView::FileLoadView(
|
||||
refresh_list();
|
||||
|
||||
on_select_entry = [&nav, this]() {
|
||||
if (entry_list[menu_view.highlighted()].is_directory) {
|
||||
if (entry_list[menu_view.highlighted_index()].is_directory) {
|
||||
load_directory_contents(get_selected_path());
|
||||
refresh_list();
|
||||
} else {
|
||||
nav_.pop();
|
||||
if (on_changed)
|
||||
on_changed(entry_list[menu_view.highlighted()].entry_path);
|
||||
on_changed(entry_list[menu_view.highlighted_index()].entry_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -282,7 +282,7 @@ FileManagerView::FileManagerView(
|
||||
refresh_list();
|
||||
|
||||
on_select_entry = [this]() {
|
||||
if (entry_list[menu_view.highlighted()].is_directory) {
|
||||
if (entry_list[menu_view.highlighted_index()].is_directory) {
|
||||
load_directory_contents(get_selected_path());
|
||||
refresh_list();
|
||||
} else
|
||||
@ -302,13 +302,13 @@ FileManagerView::FileManagerView(
|
||||
};
|
||||
|
||||
button_rename.on_select = [this, &nav](Button&) {
|
||||
name_buffer = entry_list[menu_view.highlighted()].entry_path.filename().string().substr(0, max_filename_length);
|
||||
name_buffer = entry_list[menu_view.highlighted_index()].entry_path.filename().string().substr(0, max_filename_length);
|
||||
on_rename(nav);
|
||||
};
|
||||
|
||||
button_delete.on_select = [this, &nav](Button&) {
|
||||
// Use display_modal ?
|
||||
nav.push<ModalMessageView>("Delete", "Delete " + entry_list[menu_view.highlighted()].entry_path.filename().string() + "\nAre you sure ?", YESNO,
|
||||
nav.push<ModalMessageView>("Delete", "Delete " + entry_list[menu_view.highlighted_index()].entry_path.filename().string() + "\nAre you sure ?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice)
|
||||
on_delete();
|
||||
|
@ -147,13 +147,13 @@ void FrequencySaveView::save_current_file() {
|
||||
|
||||
void FrequencySaveView::on_save_name() {
|
||||
text_prompt(nav_, &desc_buffer, 28, [this](std::string * buffer) {
|
||||
database.entries.push_back({ value_, "", *buffer });
|
||||
database.entries.push_back({ value_, 0, *buffer, SINGLE });
|
||||
save_current_file();
|
||||
});
|
||||
}
|
||||
|
||||
void FrequencySaveView::on_save_timestamp() {
|
||||
database.entries.push_back({ value_, "", live_timestamp.string() });
|
||||
database.entries.push_back({ value_, 0, live_timestamp.string(), SINGLE });
|
||||
save_current_file();
|
||||
}
|
||||
|
||||
@ -224,13 +224,26 @@ FrequencyLoadView::FrequencyLoadView(
|
||||
|
||||
on_select_frequency = [&nav, this]() {
|
||||
nav_.pop();
|
||||
if (on_changed)
|
||||
on_changed(database.entries[menu_view.highlighted()].value);
|
||||
|
||||
auto& entry = database.entries[menu_view.highlighted()];
|
||||
|
||||
if (entry.type == RANGE) {
|
||||
// User chose a frequency range entry
|
||||
if (on_range_loaded)
|
||||
on_range_loaded(entry.frequency_a, entry.frequency_b);
|
||||
else if (on_frequency_loaded)
|
||||
on_frequency_loaded(entry.frequency_a);
|
||||
// TODO: Maybe return center of range if user choses a range when the app needs a unique frequency, instead of frequency_a ?
|
||||
} else {
|
||||
// User chose an unique frequency entry
|
||||
if (on_frequency_loaded)
|
||||
on_frequency_loaded(entry.frequency_a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void FrequencyManagerView::on_edit_freq(rf::Frequency f) {
|
||||
database.entries[menu_view.highlighted()].value = f;
|
||||
database.entries[menu_view.highlighted()].frequency_a = f;
|
||||
save_freqman_file(file_list[current_category_id], database);
|
||||
refresh_list();
|
||||
}
|
||||
@ -308,7 +321,7 @@ FrequencyManagerView::FrequencyManagerView(
|
||||
};
|
||||
|
||||
button_edit_freq.on_select = [this, &nav](Button&) {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(database.entries[menu_view.highlighted()].value);
|
||||
auto new_view = nav.push<FrequencyKeypadView>(database.entries[menu_view.highlighted()].frequency_a);
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
on_edit_freq(f);
|
||||
};
|
||||
|
@ -121,7 +121,8 @@ private:
|
||||
|
||||
class FrequencyLoadView : public FreqManBaseView {
|
||||
public:
|
||||
std::function<void(rf::Frequency)> on_changed { };
|
||||
std::function<void(rf::Frequency)> on_frequency_loaded { };
|
||||
std::function<void(rf::Frequency, rf::Frequency)> on_range_loaded { };
|
||||
|
||||
FrequencyLoadView(NavigationView& nav);
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "ui_jammer.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_freqman.hpp"
|
||||
|
||||
#include "baseband_api.hpp"
|
||||
#include "string_format.hpp"
|
||||
@ -34,13 +35,12 @@ void RangeView::focus() {
|
||||
check_enabled.focus();
|
||||
}
|
||||
|
||||
extern constexpr jammer_range_t RangeView::range_presets[];
|
||||
extern constexpr Style RangeView::style_info;
|
||||
|
||||
void RangeView::update_min(rf::Frequency f) {
|
||||
void RangeView::update_start(rf::Frequency f) {
|
||||
// Change everything except max
|
||||
frequency_range.min = f;
|
||||
button_min.set_text(to_string_short_freq(f));
|
||||
button_start.set_text(to_string_short_freq(f));
|
||||
|
||||
center = (frequency_range.min + frequency_range.max) / 2;
|
||||
width = abs(frequency_range.max - frequency_range.min);
|
||||
@ -49,10 +49,10 @@ void RangeView::update_min(rf::Frequency f) {
|
||||
button_width.set_text(to_string_short_freq(width));
|
||||
}
|
||||
|
||||
void RangeView::update_max(rf::Frequency f) {
|
||||
void RangeView::update_stop(rf::Frequency f) {
|
||||
// Change everything except min
|
||||
frequency_range.max = f;
|
||||
button_max.set_text(to_string_short_freq(f));
|
||||
button_stop.set_text(to_string_short_freq(f));
|
||||
|
||||
center = (frequency_range.min + frequency_range.max) / 2;
|
||||
width = abs(frequency_range.max - frequency_range.min);
|
||||
@ -70,10 +70,10 @@ void RangeView::update_center(rf::Frequency f) {
|
||||
rf::Frequency max = min + width;
|
||||
|
||||
frequency_range.min = min;
|
||||
button_min.set_text(to_string_short_freq(min));
|
||||
button_start.set_text(to_string_short_freq(min));
|
||||
|
||||
frequency_range.max = max;
|
||||
button_max.set_text(to_string_short_freq(max));
|
||||
button_stop.set_text(to_string_short_freq(max));
|
||||
}
|
||||
|
||||
void RangeView::update_width(uint32_t w) {
|
||||
@ -86,10 +86,10 @@ void RangeView::update_width(uint32_t w) {
|
||||
rf::Frequency max = min + width;
|
||||
|
||||
frequency_range.min = min;
|
||||
button_min.set_text(to_string_short_freq(min));
|
||||
button_start.set_text(to_string_short_freq(min));
|
||||
|
||||
frequency_range.max = max;
|
||||
button_max.set_text(to_string_short_freq(max));
|
||||
button_stop.set_text(to_string_short_freq(max));
|
||||
}
|
||||
|
||||
void RangeView::paint(Painter&) {
|
||||
@ -123,9 +123,9 @@ RangeView::RangeView(NavigationView& nav) {
|
||||
add_children({
|
||||
&labels,
|
||||
&check_enabled,
|
||||
&options_preset,
|
||||
&button_min,
|
||||
&button_max,
|
||||
&button_load_range,
|
||||
&button_start,
|
||||
&button_stop,
|
||||
&button_center,
|
||||
&button_width
|
||||
});
|
||||
@ -134,22 +134,18 @@ RangeView::RangeView(NavigationView& nav) {
|
||||
frequency_range.enabled = v;
|
||||
};
|
||||
|
||||
button_min.on_select = [this, &nav](Button& button) {
|
||||
button_start.on_select = [this, &nav](Button& button) {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(frequency_range.min);
|
||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||
update_min(f);
|
||||
update_start(f);
|
||||
};
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
button_max.on_select = [this, &nav](Button& button) {
|
||||
button_stop.on_select = [this, &nav](Button& button) {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(frequency_range.max);
|
||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||
update_max(f);
|
||||
update_stop(f);
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
button_center.on_select = [this, &nav](Button& button) {
|
||||
@ -157,8 +153,6 @@ RangeView::RangeView(NavigationView& nav) {
|
||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||
update_center(f);
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
button_width.on_select = [this, &nav](Button& button) {
|
||||
@ -166,16 +160,19 @@ RangeView::RangeView(NavigationView& nav) {
|
||||
new_view->on_changed = [this, &button](rf::Frequency f) {
|
||||
update_width(f);
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
options_preset.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
update_min(range_presets[v].min);
|
||||
update_max(range_presets[v].max);
|
||||
check_enabled.set_value(true);
|
||||
button_load_range.on_select = [this, &nav](Button&) {
|
||||
auto load_view = nav.push<FrequencyLoadView>();
|
||||
load_view->on_frequency_loaded = [this](rf::Frequency value) {
|
||||
update_center(value);
|
||||
update_width(100000); // 100kHz default jamming bandwidth when loading unique frequency
|
||||
};
|
||||
load_view->on_range_loaded = [this](rf::Frequency start, rf::Frequency stop) {
|
||||
update_start(start);
|
||||
update_stop(stop);
|
||||
};
|
||||
};
|
||||
options_preset.set_selected_index(11); // ISM 868
|
||||
|
||||
check_enabled.set_value(false);
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ public:
|
||||
jammer_range_t frequency_range { false, 0, 0 };
|
||||
|
||||
private:
|
||||
void update_min(rf::Frequency f);
|
||||
void update_max(rf::Frequency f);
|
||||
void update_start(rf::Frequency f);
|
||||
void update_stop(rf::Frequency f);
|
||||
void update_center(rf::Frequency f);
|
||||
void update_width(uint32_t w);
|
||||
|
||||
@ -57,7 +57,7 @@ private:
|
||||
.foreground = Color::grey(),
|
||||
};
|
||||
|
||||
static constexpr jammer_range_t range_presets[] = {
|
||||
/*static constexpr jammer_range_t range_presets[] = {
|
||||
// GSM900 Orange
|
||||
{ true, 935000000, 945000000 }, // BW:10M
|
||||
// GSM1800 Orange
|
||||
@ -122,10 +122,9 @@ private:
|
||||
{ true, 2467000000 - 11000000, 2467000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH13
|
||||
{ true, 2472000000 - 11000000, 2472000000 + 11000000}, // BW: 22MHz
|
||||
};
|
||||
};*/
|
||||
|
||||
Labels labels {
|
||||
{ { 1 * 8, 4 * 8 }, "Preset:", Color::light_grey() },
|
||||
{ { 2 * 8, 9 * 8 + 4 }, "Start", Color::light_grey() },
|
||||
{ { 23 * 8, 9 * 8 + 4 }, "Stop", Color::light_grey() },
|
||||
{ { 12 * 8, 6 * 8 }, "Center", Color::light_grey() },
|
||||
@ -133,51 +132,21 @@ private:
|
||||
};
|
||||
|
||||
Checkbox check_enabled {
|
||||
{ 7 * 8, 4 },
|
||||
{ 1 * 8, 4 },
|
||||
12,
|
||||
"Enable range",
|
||||
false
|
||||
"Enable range"
|
||||
};
|
||||
|
||||
OptionsField options_preset {
|
||||
{ 9 * 8, 4 * 8 },
|
||||
19,
|
||||
{
|
||||
{ "GSM900 Orange FR", 0 },
|
||||
{ "GSM1800 Orange FR", 1 },
|
||||
{ "GSM900 SFR FR", 2 },
|
||||
{ "GSM1800 SFR FR", 3 },
|
||||
{ "GSM900 Bouygues FR", 4 },
|
||||
{ "GSM1800 Bouygues FR", 5 },
|
||||
{ "GSM Free FR", 6 },
|
||||
{ "GSM-R FR", 7 },
|
||||
{ "DECT", 8 },
|
||||
{ "Optifib", 9 },
|
||||
{ "ISM 433", 10 },
|
||||
{ "ISM 868", 11 },
|
||||
{ "GPS L1", 12 },
|
||||
{ "GPS L2", 13 },
|
||||
{ "WLAN 2.4G CH1", 14 },
|
||||
{ "WLAN 2.4G CH2", 15 },
|
||||
{ "WLAN 2.4G CH3", 16 },
|
||||
{ "WLAN 2.4G CH4", 17 },
|
||||
{ "WLAN 2.4G CH5", 18 },
|
||||
{ "WLAN 2.4G CH6", 19 },
|
||||
{ "WLAN 2.4G CH7", 20 },
|
||||
{ "WLAN 2.4G CH8", 21 },
|
||||
{ "WLAN 2.4G CH9", 22 },
|
||||
{ "WLAN 2.4G CH10", 23 },
|
||||
{ "WLAN 2.4G CH11", 24 },
|
||||
{ "WLAN 2.4G CH12", 25 },
|
||||
{ "WLAN 2.4G CH13", 26 }
|
||||
}
|
||||
Button button_load_range {
|
||||
{ 18 * 8, 4, 12 * 8, 24 },
|
||||
"Load range"
|
||||
};
|
||||
|
||||
Button button_min {
|
||||
Button button_start {
|
||||
{ 0 * 8, 6 * 16, 11 * 8, 28 },
|
||||
""
|
||||
};
|
||||
Button button_max {
|
||||
Button button_stop {
|
||||
{ 19 * 8, 6 * 16, 11 * 8, 28 },
|
||||
""
|
||||
};
|
||||
|
@ -27,9 +27,15 @@ namespace ui {
|
||||
|
||||
/* MenuItemView **********************************************************/
|
||||
|
||||
void MenuItemView::set_item(MenuItem* item_) {
|
||||
item = item_;
|
||||
}
|
||||
|
||||
void MenuItemView::select() {
|
||||
if( item.on_select ) {
|
||||
item.on_select();
|
||||
if (!item) return;
|
||||
|
||||
if( item->on_select ) {
|
||||
item->on_select();
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,14 +52,16 @@ void MenuItemView::unhighlight() {
|
||||
void MenuItemView::paint(Painter& painter) {
|
||||
Coord offset_x;
|
||||
|
||||
if (!item) return;
|
||||
|
||||
const auto r = screen_rect();
|
||||
|
||||
const auto paint_style = (highlighted() && (parent()->has_focus() || keep_highlight_)) ? style().invert() : style();
|
||||
const auto paint_style = (highlighted() && (parent()->has_focus() || keep_highlight)) ? style().invert() : style();
|
||||
|
||||
const auto font_height = paint_style.font.line_height();
|
||||
|
||||
ui::Color final_item_color = (highlighted() && (parent()->has_focus() || keep_highlight_)) ? paint_style.foreground : item.color;
|
||||
ui::Color final_bg_color = (highlighted() && (parent()->has_focus() || keep_highlight_)) ? item.color : paint_style.background;
|
||||
ui::Color final_item_color = (highlighted() && (parent()->has_focus() || keep_highlight)) ? paint_style.foreground : item->color;
|
||||
ui::Color final_bg_color = (highlighted() && (parent()->has_focus() || keep_highlight)) ? item->color : paint_style.background;
|
||||
|
||||
if (final_item_color.v == final_bg_color.v) final_item_color = paint_style.foreground;
|
||||
|
||||
@ -62,10 +70,10 @@ void MenuItemView::paint(Painter& painter) {
|
||||
final_bg_color
|
||||
);
|
||||
|
||||
if (item.bitmap) {
|
||||
if (item->bitmap) {
|
||||
painter.draw_bitmap(
|
||||
{ r.location().x() + 4, r.location().y() + 4 },
|
||||
*item.bitmap,
|
||||
*item->bitmap,
|
||||
final_item_color,
|
||||
final_bg_color
|
||||
);
|
||||
@ -82,7 +90,7 @@ void MenuItemView::paint(Painter& painter) {
|
||||
painter.draw_string(
|
||||
{ r.location().x() + offset_x, r.location().y() + (r.size().height() - font_height) / 2 },
|
||||
text_style,
|
||||
item.text
|
||||
item->text
|
||||
);
|
||||
}
|
||||
|
||||
@ -91,7 +99,7 @@ void MenuItemView::paint(Painter& painter) {
|
||||
MenuView::MenuView(
|
||||
Rect new_parent_rect,
|
||||
bool keep_highlight
|
||||
) : keep_highlight_ { keep_highlight }
|
||||
) : keep_highlight { keep_highlight }
|
||||
{
|
||||
set_parent_rect(new_parent_rect);
|
||||
|
||||
@ -108,45 +116,65 @@ MenuView::MenuView(
|
||||
|
||||
MenuView::~MenuView() {
|
||||
rtc_time::signal_tick_second -= signal_token_tick_second;
|
||||
for (auto item : menu_items_) {
|
||||
|
||||
for (auto item : menu_item_views) {
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
||||
|
||||
View::set_parent_rect(new_parent_rect);
|
||||
|
||||
displayed_max_ = (parent_rect().size().height() / 24);
|
||||
arrow_more.set_parent_rect( { 228, (Coord)(displayed_max_ * item_height), 8, 8 } );
|
||||
displayed_max = (parent_rect().size().height() / item_height);
|
||||
arrow_more.set_parent_rect( { 228, (Coord)(displayed_max * item_height), 8, 8 } );
|
||||
|
||||
// TODO: Clean this up :(
|
||||
if (menu_item_views.size()) {
|
||||
|
||||
for (auto item : menu_item_views) {
|
||||
remove_child(item);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
menu_item_views.clear();
|
||||
|
||||
for (size_t c = 0; c < displayed_max; c++) {
|
||||
auto item = new MenuItemView { keep_highlight };
|
||||
menu_item_views.push_back(item);
|
||||
add_child(item);
|
||||
|
||||
auto y_pos = c * item_height;
|
||||
item->set_parent_rect({
|
||||
{ 0, y_pos },
|
||||
{ size().width(), (Coord)item_height }
|
||||
});
|
||||
}
|
||||
|
||||
update_items();
|
||||
}
|
||||
|
||||
void MenuView::on_tick_second() {
|
||||
if (more_ && blink_)
|
||||
if (more && blink)
|
||||
arrow_more.set_foreground(Color::white());
|
||||
else
|
||||
arrow_more.set_foreground(Color::black());
|
||||
|
||||
blink_ = !blink_;
|
||||
blink = !blink;
|
||||
|
||||
arrow_more.set_dirty();
|
||||
}
|
||||
|
||||
void MenuView::clear() {
|
||||
for (auto item : menu_items_) {
|
||||
remove_child(item);
|
||||
delete item;
|
||||
for (auto item : menu_item_views) {
|
||||
item->set_item(nullptr);
|
||||
}
|
||||
menu_items_.clear();
|
||||
|
||||
update_items();
|
||||
menu_items.clear();
|
||||
}
|
||||
|
||||
void MenuView::add_item(MenuItem new_item) {
|
||||
auto item = new MenuItemView { new_item, keep_highlight_ };
|
||||
|
||||
menu_items_.push_back(item);
|
||||
add_child(item);
|
||||
menu_items.push_back(new_item);
|
||||
|
||||
update_items();
|
||||
}
|
||||
@ -161,38 +189,34 @@ void MenuView::update_items() {
|
||||
size_t i = 0;
|
||||
int32_t y_pos;
|
||||
|
||||
if (menu_items_.size() > displayed_max_ + offset_) {
|
||||
more_ = true;
|
||||
blink_ = true;
|
||||
if (menu_items.size() > displayed_max + offset) {
|
||||
more = true;
|
||||
blink = true;
|
||||
} else
|
||||
more_ = false;
|
||||
more = false;
|
||||
|
||||
for (auto item : menu_item_views) {
|
||||
if (i + offset >= menu_items.size()) break;
|
||||
|
||||
// Assign item data to MenuItemViews according to offset
|
||||
item->set_item(&menu_items[i + offset]);
|
||||
item->set_dirty();
|
||||
|
||||
if (highlighted_item == (i + offset)) {
|
||||
item->highlight();
|
||||
} else
|
||||
item->unhighlight();
|
||||
|
||||
for (auto item : menu_items_) {
|
||||
y_pos = (i - offset_) * item_height;
|
||||
item->set_parent_rect({
|
||||
{ 0, y_pos },
|
||||
{ size().width(), (Coord)item_height }
|
||||
});
|
||||
if ((y_pos < 0) || (y_pos > (Coord)(screen_rect().size().height() - item_height)))
|
||||
item->hidden(true);
|
||||
else
|
||||
item->hidden(false);
|
||||
i++;
|
||||
}
|
||||
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
MenuItemView* MenuView::item_view(size_t index) const {
|
||||
return menu_items_[index];
|
||||
}
|
||||
|
||||
size_t MenuView::highlighted() const {
|
||||
return highlighted_;
|
||||
return menu_item_views[index];
|
||||
}
|
||||
|
||||
bool MenuView::set_highlighted(int32_t new_value) {
|
||||
int32_t item_count = (int32_t)menu_items_.size();
|
||||
int32_t item_count = (int32_t)menu_items.size();
|
||||
|
||||
if (new_value < 0)
|
||||
return false;
|
||||
@ -200,42 +224,49 @@ bool MenuView::set_highlighted(int32_t new_value) {
|
||||
if (new_value >= item_count)
|
||||
new_value = item_count - 1;
|
||||
|
||||
if (((uint32_t)new_value > offset_) && ((new_value - offset_) >= displayed_max_)) {
|
||||
if (((uint32_t)new_value > offset) && ((new_value - offset) >= displayed_max)) {
|
||||
// Shift MenuView up
|
||||
offset_ = new_value - displayed_max_ + 1;
|
||||
highlighted_item = new_value;
|
||||
offset = new_value - displayed_max + 1;
|
||||
update_items();
|
||||
} else if ((uint32_t)new_value < offset_) {
|
||||
} else if ((uint32_t)new_value < offset) {
|
||||
// Shift MenuView down
|
||||
offset_ = new_value;
|
||||
highlighted_item = new_value;
|
||||
offset = new_value;
|
||||
update_items();
|
||||
} else {
|
||||
// Just update highlight
|
||||
item_view(highlighted_item - offset)->unhighlight();
|
||||
highlighted_item = new_value;
|
||||
item_view(highlighted_item - offset)->highlight();
|
||||
}
|
||||
|
||||
item_view(highlighted_)->unhighlight();
|
||||
highlighted_ = new_value;
|
||||
item_view(highlighted_)->highlight();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t MenuView::highlighted_index() {
|
||||
return highlighted_item;
|
||||
}
|
||||
|
||||
void MenuView::on_focus() {
|
||||
item_view(highlighted())->highlight();
|
||||
item_view(highlighted_item)->highlight();
|
||||
}
|
||||
|
||||
void MenuView::on_blur() {
|
||||
if (!keep_highlight_) item_view(highlighted())->unhighlight();
|
||||
if (!keep_highlight) item_view(highlighted_item)->unhighlight();
|
||||
}
|
||||
|
||||
bool MenuView::on_key(const KeyEvent key) {
|
||||
switch(key) {
|
||||
case KeyEvent::Up:
|
||||
return set_highlighted(highlighted() - 1);
|
||||
return set_highlighted(highlighted_item - 1);
|
||||
|
||||
case KeyEvent::Down:
|
||||
return set_highlighted(highlighted() + 1);
|
||||
return set_highlighted(highlighted_item + 1);
|
||||
|
||||
case KeyEvent::Select:
|
||||
case KeyEvent::Right:
|
||||
item_view(highlighted())->select();
|
||||
item_view(highlighted_item - offset)->select();
|
||||
return true;
|
||||
|
||||
case KeyEvent::Left:
|
||||
@ -250,7 +281,7 @@ bool MenuView::on_key(const KeyEvent key) {
|
||||
}
|
||||
|
||||
bool MenuView::on_encoder(const EncoderEvent event) {
|
||||
set_highlighted(highlighted() + event);
|
||||
set_highlighted(highlighted_item + event);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -49,22 +49,27 @@ struct MenuItem {
|
||||
class MenuItemView : public Widget {
|
||||
public:
|
||||
MenuItemView(
|
||||
MenuItem item,
|
||||
bool keep_highlight
|
||||
) : item { item },
|
||||
keep_highlight_ { keep_highlight }
|
||||
) : keep_highlight { keep_highlight }
|
||||
{
|
||||
}
|
||||
|
||||
MenuItemView(const MenuItemView&) = delete;
|
||||
MenuItemView(MenuItemView&&) = delete;
|
||||
MenuItemView& operator=(const MenuItemView&) = delete;
|
||||
MenuItemView& operator=(MenuItemView&&) = delete;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
void set_item(MenuItem* item_);
|
||||
|
||||
void select();
|
||||
void highlight();
|
||||
void unhighlight();
|
||||
|
||||
private:
|
||||
const MenuItem item;
|
||||
bool keep_highlight_ = false;
|
||||
MenuItem* item { nullptr };
|
||||
bool keep_highlight = false;
|
||||
};
|
||||
|
||||
class MenuView : public View {
|
||||
@ -81,8 +86,8 @@ public:
|
||||
|
||||
MenuItemView* item_view(size_t index) const;
|
||||
|
||||
size_t highlighted() const;
|
||||
bool set_highlighted(int32_t new_value);
|
||||
uint32_t highlighted_index();
|
||||
|
||||
void set_parent_rect(const Rect new_parent_rect) override;
|
||||
void on_focus() override;
|
||||
@ -94,10 +99,11 @@ private:
|
||||
void update_items();
|
||||
void on_tick_second();
|
||||
|
||||
bool keep_highlight_ { false };
|
||||
bool keep_highlight { false };
|
||||
|
||||
SignalToken signal_token_tick_second { };
|
||||
std::vector<MenuItemView*> menu_items_ { };
|
||||
std::vector<MenuItem> menu_items { };
|
||||
std::vector<MenuItemView*> menu_item_views { };
|
||||
|
||||
Image arrow_more {
|
||||
{ 228, 320 - 8, 8, 8 },
|
||||
@ -107,11 +113,11 @@ private:
|
||||
};
|
||||
|
||||
const size_t item_height = 24;
|
||||
bool blink_ = false;
|
||||
bool more_ = false;
|
||||
size_t displayed_max_ { 0 };
|
||||
size_t highlighted_ { 0 };
|
||||
size_t offset_ { 0 };
|
||||
bool blink = false;
|
||||
bool more = false;
|
||||
size_t displayed_max { 0 };
|
||||
size_t highlighted_item { 0 };
|
||||
size_t offset { 0 };
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
@ -364,10 +364,10 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receivers, [&nav](){ nav.push<ReceiversMenuView>(); } },
|
||||
{ "Transmitters", ui::Color::green(), &bitmap_icon_transmit, [&nav](){ nav.push<TransmittersMenuView>(); } },
|
||||
{ "Capture", ui::Color::blue(), &bitmap_icon_capture, [&nav](){ nav.push<CaptureAppView>(); } },
|
||||
{ "Replay", ui::Color::grey(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||
{ "Replay", ui::Color::purple(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||
{ "Scanner/search", ui::Color::orange(), &bitmap_icon_closecall, [&nav](){ nav.push<ScannerView>(); } },
|
||||
{ "Wave file viewer", ui::Color::blue(), nullptr, [&nav](){ nav.push<ViewWavView>(); } },
|
||||
{ "Utilities", ui::Color::purple(), &bitmap_icon_utilities, [&nav](){ nav.push<UtilitiesMenuView>(); } },
|
||||
{ "Utilities", ui::Color::light_grey(), &bitmap_icon_utilities, [&nav](){ nav.push<UtilitiesMenuView>(); } },
|
||||
{ "Setup", ui::Color::white(), &bitmap_icon_setup, [&nav](){ nav.push<SetupMenuView>(); } },
|
||||
//{ "Debug", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugMenuView>(); } },
|
||||
{ "HackRF mode", ui::Color::white(), &bitmap_icon_hackrf, [this, &nav](){ hackrf_mode(nav); } },
|
||||
|
@ -149,7 +149,7 @@ FrequencyKeypadView::FrequencyKeypadView(
|
||||
};
|
||||
button_load.on_select = [this, &nav](Button&) {
|
||||
auto load_view = nav.push<FrequencyLoadView>();
|
||||
load_view->on_changed = [this](rf::Frequency value) {
|
||||
load_view->on_frequency_loaded = [this](rf::Frequency value) {
|
||||
set_value(value);
|
||||
};
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ private:
|
||||
};
|
||||
|
||||
Checkbox check_log {
|
||||
{ 22 * 8, 2 * 16 + 12 },
|
||||
{ 22 * 8, 3 * 16 },
|
||||
3,
|
||||
"Log"
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ Packet::Packet(
|
||||
{
|
||||
if (type_ == Type::Meteomodem_unknown) {
|
||||
// Right now we're just sure that the sync is from a Meteomodem sonde, differentiate between models now
|
||||
const uint32_t id_byte = reader_bi_m.read(1 * 8, 16);
|
||||
const uint32_t id_byte = reader_bi_m.read(0 * 8, 16);
|
||||
|
||||
if (id_byte == 0x649F)
|
||||
type_ = Type::Meteomodem_M10;
|
||||
@ -128,7 +128,7 @@ std::string Packet::serial_number() const {
|
||||
to_string_dec_uint(reader_bi_m.read(93 * 8 + 27, 13), 4, '0');
|
||||
|
||||
} else
|
||||
return 0;
|
||||
return "?";
|
||||
}
|
||||
|
||||
FormattedSymbols Packet::symbols_formatted() const {
|
||||
|
Binary file not shown.
74
sdcard/FREQMAN/JAMMER.TXT
Normal file
74
sdcard/FREQMAN/JAMMER.TXT
Normal file
@ -0,0 +1,74 @@
|
||||
a=935000000,b=945000000,d=GSM900 Orange FR
|
||||
a=1808000000,b=1832000000,d=GSM1800 Orange FR
|
||||
a=950000000,b=960000000,d=GSM900 SFR FR
|
||||
a=1832000000,b=1853000000,d=GSM1800 SFR FR
|
||||
a=925000000,b=935000000,d=GSM900 Bouygues FR
|
||||
a=1858000000,b=1880000000,d=GSM1800 Bouygues FR
|
||||
a=945000000,b=950000000,d=GSM Free FR
|
||||
a=921000000,b=925000000,d=GSM-R FR
|
||||
a=1880000000,b=1900000000,d=DECT
|
||||
a=162930000,b=162970000,d=PMV AFSK
|
||||
a=433050000,b=434790000,d=ISM 433
|
||||
a=868000000,b=868200000,d=ISM 868
|
||||
a=1574920000,b=1575920000,d=GPS L1
|
||||
a=1226600000,b=1228600000,d=GPS L2
|
||||
a=2401000000,b=2423000000,d=WLAN 2.4G CH1
|
||||
a=2406000000,b=2428000000,d=WLAN 2.4G CH2
|
||||
a=2411000000,b=2433000000,d=WLAN 2.4G CH3
|
||||
a=2416000000,b=2438000000,d=WLAN 2.4G CH4
|
||||
a=2421000000,b=2443000000,d=WLAN 2.4G CH5
|
||||
a=2426000000,b=2448000000,d=WLAN 2.4G CH6
|
||||
a=2431000000,b=2453000000,d=WLAN 2.4G CH7
|
||||
a=2436000000,b=2458000000,d=WLAN 2.4G CH8
|
||||
a=2441000000,b=2463000000,d=WLAN 2.4G CH9
|
||||
a=2446000000,b=2468000000,d=WLAN 2.4G CH10
|
||||
a=2451000000,b=2473000000,d=WLAN 2.4G CH11
|
||||
a=2456000000,b=2478000000,d=WLAN 2.4G CH12
|
||||
a=2461000000,b=2483000000,d=WLAN 2.4G CH13
|
||||
a=5170000000,b=5190000000,d=WLAN 5G CH36
|
||||
a=5170000000,b=5210000000,d=WLAN 5G CH38
|
||||
a=5190000000,b=5210000000,d=WLAN 5G CH40
|
||||
a=5170000000,b=5250000000,d=WLAN 5G CH42
|
||||
a=5210000000,b=5230000000,d=WLAN 5G CH44
|
||||
a=5210000000,b=5250000000,d=WLAN 5G CH46
|
||||
a=5230000000,b=5250000000,d=WLAN 5G CH48
|
||||
a=5170000000,b=5330000000,d=WLAN 5G CH50
|
||||
a=5250000000,b=5270000000,d=WLAN 5G CH52
|
||||
a=5250000000,b=5290000000,d=WLAN 5G CH54
|
||||
a=5270000000,b=5290000000,d=WLAN 5G CH56
|
||||
a=5250000000,b=5330000000,d=WLAN 5G CH58
|
||||
a=5290000000,b=5310000000,d=WLAN 5G CH60
|
||||
a=5290000000,b=5330000000,d=WLAN 5G CH62
|
||||
a=5310000000,b=5330000000,d=WLAN 5G CH64
|
||||
a=5490000000,b=5510000000,d=WLAN 5G CH100
|
||||
a=5490000000,b=5530000000,d=WLAN 5G CH102
|
||||
a=5510000000,b=5530000000,d=WLAN 5G CH104
|
||||
a=5490000000,b=5570000000,d=WLAN 5G CH106
|
||||
a=5530000000,b=5550000000,d=WLAN 5G CH108
|
||||
a=5530000000,b=5570000000,d=WLAN 5G CH110
|
||||
a=5550000000,b=5570000000,d=WLAN 5G CH112
|
||||
a=5490000000,b=5650000000,d=WLAN 5G CH114
|
||||
a=5570000000,b=5590000000,d=WLAN 5G CH116
|
||||
a=5570000000,b=5610000000,d=WLAN 5G CH118
|
||||
a=5590000000,b=5610000000,d=WLAN 5G CH120
|
||||
a=5570000000,b=5650000000,d=WLAN 5G CH122
|
||||
a=5610000000,b=5630000000,d=WLAN 5G CH124
|
||||
a=5610000000,b=5650000000,d=WLAN 5G CH126
|
||||
a=5630000000,b=5650000000,d=WLAN 5G CH128
|
||||
a=5650000000,b=5670000000,d=WLAN 5G CH132
|
||||
a=5650000000,b=5690000000,d=WLAN 5G CH134
|
||||
a=5670000000,b=5690000000,d=WLAN 5G CH136
|
||||
a=5650000000,b=5730000000,d=WLAN 5G CH138
|
||||
a=5690000000,b=5710000000,d=WLAN 5G CH140
|
||||
a=5690000000,b=5730000000,d=WLAN 5G CH142
|
||||
a=5710000000,b=5730000000,d=WLAN 5G CH144
|
||||
a=5735000000,b=5755000000,d=WLAN 5G CH149
|
||||
a=5735000000,b=5775000000,d=WLAN 5G CH151
|
||||
a=5755000000,b=5775000000,d=WLAN 5G CH153
|
||||
a=5735000000,b=5815000000,d=WLAN 5G CH155
|
||||
a=5775000000,b=5795000000,d=WLAN 5G CH157
|
||||
a=5775000000,b=5815000000,d=WLAN 5G CH159
|
||||
a=5795000000,b=5815000000,d=WLAN 5G CH161
|
||||
a=5815000000,b=5835000000,d=WLAN 5G CH165
|
||||
a=5835000000,b=5855000000,d=WLAN 5G CH169
|
||||
a=5855000000,b=5875000000,d=WLAN 5G CH173
|
Loading…
Reference in New Issue
Block a user