Gfx widget and Radio (#2685)

* widgetize
* gfx and Radio improvement
* format + handle not wfm visual states
* wf or gf
This commit is contained in:
Totoo
2025-06-07 11:43:07 +02:00
committed by GitHub
parent 37ca7a601c
commit 00853f526a
8 changed files with 350 additions and 150 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ __attribute__((section(".external_app.app_fmradio.application_information"), use
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "FM Radio",
/*.app_name = */ "Radio",
/*.bitmap_data = */ {
0x00,
0x00,
+45 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2024 HT Otto
* Copyright (C) 2024 HTotoo
* Copyright (C) 2025 RocketGod - Added modes from my Flipper Zero RF Jammer App - https://betaskynet.com
*
* This file is part of PortaPack.
@@ -39,6 +39,28 @@ void FmRadioView::focus() {
field_frequency.focus();
}
void FmRadioView::show_hide_gfx(bool show) {
gr.hidden(!show);
gr.set_paused(!show);
waveform.set_paused(show);
btn_fav_0.hidden(show);
btn_fav_1.hidden(show);
btn_fav_2.hidden(show);
btn_fav_3.hidden(show);
btn_fav_4.hidden(show);
btn_fav_5.hidden(show);
btn_fav_6.hidden(show);
btn_fav_7.hidden(show);
btn_fav_8.hidden(show);
btn_fav_9.hidden(show);
txt_save_help.hidden(show);
btn_fav_save.hidden(show);
field_bw.hidden(show);
field_modulation.hidden(show);
text_mode_label.hidden(show);
set_dirty();
}
void FmRadioView::change_mode(int32_t mod) {
field_bw.on_change = [this](size_t n, OptionsField::value_t) { (void)n; };
@@ -48,8 +70,8 @@ void FmRadioView::change_mode(int32_t mod) {
audio_spectrum_update = false; // Reset spectrum update flag
std::fill(audio_spectrum, audio_spectrum + 128, 0); // Clear spectrum buffer
ReceiverModel::Mode receiver_mode = static_cast<ReceiverModel::Mode>(mod);
waveform.set_dirty();
receiver_mode = static_cast<ReceiverModel::Mode>(mod);
bool is_ssb = (mod == static_cast<int32_t>(ReceiverModel::Mode::AMAudio) &&
(field_modulation.selected_index() == 3 || field_modulation.selected_index() == 4));
@@ -70,6 +92,7 @@ void FmRadioView::change_mode(int32_t mod) {
radio_bw = index;
receiver_model.set_am_configuration(n);
};
show_hide_gfx(false);
break;
case static_cast<int32_t>(ReceiverModel::Mode::NarrowbandFMAudio):
audio_sampling_rate = audio::Rate::Hz_24000;
@@ -82,6 +105,7 @@ void FmRadioView::change_mode(int32_t mod) {
radio_bw = index;
receiver_model.set_nbfm_configuration(n);
};
show_hide_gfx(false);
break;
case static_cast<int32_t>(ReceiverModel::Mode::WidebandFMAudio):
audio_sampling_rate = audio::Rate::Hz_48000;
@@ -106,7 +130,6 @@ void FmRadioView::change_mode(int32_t mod) {
audio::set_rate(audio_sampling_rate);
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack
receiver_model.enable();
}
@@ -136,8 +159,10 @@ FmRadioView::FmRadioView(NavigationView& nav)
&btn_fav_9,
&audio,
&waveform,
&rssi});
&rssi,
&gr});
txt_save_help.set_focusable(false);
txt_save_help.visible(false);
for (uint8_t i = 0; i < 12; ++i) {
if (freq_fav_list[i].frequency == 0) {
@@ -179,7 +204,20 @@ FmRadioView::FmRadioView(NavigationView& nav)
}
};
waveform.on_select = [this](Waveform&) {
if (receiver_mode != ReceiverModel::Mode::WidebandFMAudio) { // only there is spectrum message
return;
}
show_hide_gfx(!btn_fav_0.hidden());
};
gr.set_theme(themes[current_theme].base_color, themes[current_theme].peak_color);
gr.on_select = [this](GraphEq&) {
current_theme = (current_theme + 1) % themes.size();
gr.set_theme(themes[current_theme].base_color, themes[current_theme].peak_color);
gr.set_paused(false);
};
update_fav_btn_texts();
show_hide_gfx(false);
}
void FmRadioView::on_btn_clicked(uint8_t i) {
@@ -226,8 +264,9 @@ FmRadioView::~FmRadioView() {
}
void FmRadioView::on_audio_spectrum() {
if (gr.visible() && audio_spectrum_data) gr.update_audio_spectrum(*audio_spectrum_data);
if (audio_spectrum_data && audio_spectrum_data->db.size() <= 128) {
for (size_t i = 0; i < audio_spectrum_data->db.size(); i++) {
for (size_t i = 0; i < audio_spectrum_data->db.size(); ++i) {
audio_spectrum[i] = ((int16_t)audio_spectrum_data->db[i] - 127) * 256;
}
waveform.set_dirty();
+37 -4
View File
@@ -58,13 +58,14 @@ class FmRadioView : public View {
void focus() override;
std::string title() const override { return "FM radio"; };
std::string title() const override { return "Radio"; };
private:
NavigationView& nav_;
RxRadioState radio_state_{};
int16_t audio_spectrum[128]{0};
bool audio_spectrum_update = false;
ReceiverModel::Mode receiver_mode = ReceiverModel::Mode::WidebandFMAudio;
AudioSpectrum* audio_spectrum_data{nullptr};
struct Favorite {
rf::Frequency frequency = 0;
@@ -74,7 +75,7 @@ class FmRadioView : public View {
Favorite freq_fav_list[12];
audio::Rate audio_sampling_rate = audio::Rate::Hz_48000;
uint8_t radio_bw = 0;
uint32_t current_theme{0};
app_settings::SettingsManager settings_{
"rx_fmradio",
app_settings::Mode::RX,
@@ -114,7 +115,8 @@ class FmRadioView : public View {
{"favlist9_bw"sv, &freq_fav_list[9].bandwidth},
{"favlist10_bw"sv, &freq_fav_list[10].bandwidth},
{"favlist11_bw"sv, &freq_fav_list[11].bandwidth},
{"radio_bw"sv, &radio_bw}}};
{"radio_bw"sv, &radio_bw},
{"theme"sv, &current_theme}}};
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
@@ -157,7 +159,7 @@ class FmRadioView : public View {
{21 * 8, 10, 6 * 8, 4}};
Waveform waveform{
{0, 20, screen_width, 2 * 16},
{0, 20, UI_POS_MAXWIDTH, 2 * 16},
audio_spectrum,
128,
0,
@@ -165,6 +167,8 @@ class FmRadioView : public View {
Theme::getInstance()->bg_darkest->foreground,
true};
GraphEq gr{{2, FMR_BTNGRID_TOP, UI_POS_MAXWIDTH - 4, UI_POS_MAXHEIGHT - FMR_BTNGRID_TOP}, true};
Button btn_fav_0{{2, FMR_BTNGRID_TOP + 0 * 34, 10 * 8, 28}, "---"};
Button btn_fav_1{{2 + 15 * 8, FMR_BTNGRID_TOP + 0 * 34, 10 * 8, 28}, "---"};
Button btn_fav_2{{2, FMR_BTNGRID_TOP + 1 * 34, 10 * 8, 28}, "---"};
@@ -185,6 +189,35 @@ class FmRadioView : public View {
void on_audio_spectrum();
void change_mode(int32_t mod);
void show_hide_gfx(bool show);
struct ColorTheme {
Color base_color;
Color peak_color;
};
const std::array<ColorTheme, 20> themes{
ColorTheme{Color(255, 0, 255), Color(255, 255, 255)},
ColorTheme{Color(0, 255, 0), Color(255, 0, 0)},
ColorTheme{Color(0, 0, 255), Color(255, 255, 0)},
ColorTheme{Color(255, 128, 0), Color(255, 0, 128)},
ColorTheme{Color(128, 0, 255), Color(0, 255, 255)},
ColorTheme{Color(255, 255, 0), Color(0, 255, 128)},
ColorTheme{Color(255, 0, 0), Color(0, 128, 255)},
ColorTheme{Color(0, 255, 128), Color(255, 128, 255)},
ColorTheme{Color(128, 128, 128), Color(255, 255, 255)},
ColorTheme{Color(255, 64, 0), Color(0, 255, 64)},
ColorTheme{Color(0, 128, 128), Color(255, 192, 0)},
ColorTheme{Color(0, 255, 0), Color(0, 128, 0)},
ColorTheme{Color(32, 64, 32), Color(0, 255, 0)},
ColorTheme{Color(64, 0, 128), Color(255, 0, 255)},
ColorTheme{Color(0, 64, 0), Color(0, 255, 128)},
ColorTheme{Color(255, 255, 255), Color(0, 0, 255)},
ColorTheme{Color(128, 0, 0), Color(255, 128, 0)},
ColorTheme{Color(0, 128, 255), Color(255, 255, 128)},
ColorTheme{Color(64, 64, 64), Color(255, 0, 0)},
ColorTheme{Color(255, 192, 0), Color(0, 64, 128)}};
MessageHandlerRegistration message_handler_audio_spectrum{
Message::ID::AudioSpectrum,
[this](const Message* const p) {