From 5daa0dfbb12a2927cb6cd0ccd5a441dd90af718b Mon Sep 17 00:00:00 2001 From: Kyle Reed <3761006+kallanreed@users.noreply.github.com> Date: Sun, 18 Jun 2023 12:11:04 -0700 Subject: [PATCH] Consolidate frequency field on_edit (#1166) --- firmware/application/apps/acars_app.cpp | 16 +---- firmware/application/apps/acars_app.hpp | 12 ++-- .../application/apps/analog_audio_app.cpp | 13 ---- .../application/apps/analog_audio_app.hpp | 17 ++--- firmware/application/apps/analog_tv_app.cpp | 20 ------ firmware/application/apps/analog_tv_app.hpp | 19 ++--- firmware/application/apps/capture_app.cpp | 16 +---- firmware/application/apps/capture_app.hpp | 17 ++--- firmware/application/apps/gps_sim_app.cpp | 11 --- firmware/application/apps/gps_sim_app.hpp | 5 +- firmware/application/apps/pocsag_app.cpp | 43 +++++------ firmware/application/apps/pocsag_app.hpp | 15 ++-- firmware/application/apps/replay_app.cpp | 17 +---- firmware/application/apps/replay_app.hpp | 6 +- firmware/application/apps/ui_afsk_rx.cpp | 21 ++---- firmware/application/apps/ui_afsk_rx.hpp | 15 ++-- firmware/application/apps/ui_aprs_rx.cpp | 17 +---- firmware/application/apps/ui_aprs_rx.hpp | 16 ++--- firmware/application/apps/ui_btle_rx.cpp | 21 ++---- firmware/application/apps/ui_btle_rx.hpp | 17 ++--- firmware/application/apps/ui_mictx.hpp | 2 + firmware/application/apps/ui_modemsetup.hpp | 2 - firmware/application/apps/ui_nrf_rx.cpp | 19 +---- firmware/application/apps/ui_nrf_rx.hpp | 15 ++-- firmware/application/apps/ui_search.cpp | 20 ++---- firmware/application/apps/ui_search.hpp | 11 +-- firmware/application/apps/ui_sonde.cpp | 16 +---- firmware/application/apps/ui_sonde.hpp | 9 +-- .../application/apps/ui_spectrum_painter.cpp | 10 --- .../application/apps/ui_spectrum_painter.hpp | 4 +- firmware/application/apps/ui_test.cpp | 14 +--- firmware/application/apps/ui_test.hpp | 6 +- firmware/application/apps/ui_whipcalc.cpp | 15 ++-- firmware/application/apps/ui_whipcalc.hpp | 7 +- firmware/application/ui/ui_freq_field.hpp | 72 +++++++++++++++++++ firmware/application/ui/ui_receiver.hpp | 9 ++- 36 files changed, 215 insertions(+), 350 deletions(-) create mode 100644 firmware/application/ui/ui_freq_field.hpp diff --git a/firmware/application/apps/acars_app.cpp b/firmware/application/apps/acars_app.cpp index d44dc8fba..c041726c3 100644 --- a/firmware/application/apps/acars_app.cpp +++ b/firmware/application/apps/acars_app.cpp @@ -55,7 +55,8 @@ void ACARSLogger::log_raw_data(const acars::Packet& packet, const uint32_t frequ namespace ui { -ACARSAppView::ACARSAppView(NavigationView& nav) { +ACARSAppView::ACARSAppView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_acars); add_children({&rssi, @@ -69,19 +70,6 @@ ACARSAppView::ACARSAppView(NavigationView& nav) { receiver_model.enable(); - field_frequency.set_value(receiver_model.target_frequency()); - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; - check_log.set_value(logging); check_log.on_select = [this](Checkbox&, bool v) { logging = v; diff --git a/firmware/application/apps/acars_app.hpp b/firmware/application/apps/acars_app.hpp index 84b46a409..72097403f 100644 --- a/firmware/application/apps/acars_app.hpp +++ b/firmware/application/apps/acars_app.hpp @@ -27,6 +27,7 @@ #include "radio_state.hpp" #include "ui_widget.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_rssi.hpp" #include "log_file.hpp" @@ -57,6 +58,7 @@ class ACARSAppView : public View { std::string title() const override { return "ACARS (WIP)"; }; private: + NavigationView& nav_; RxRadioState radio_state_{ 1750000 /* bandwidth */, 2457600 /* sampling rate */ @@ -74,15 +76,13 @@ class ACARSAppView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 8}, - }; + nav_}; Checkbox check_log{ {22 * 8, 21}, 3, diff --git a/firmware/application/apps/analog_audio_app.cpp b/firmware/application/apps/analog_audio_app.cpp index 879f96048..ee7d2105b 100644 --- a/firmware/application/apps/analog_audio_app.cpp +++ b/firmware/application/apps/analog_audio_app.cpp @@ -152,19 +152,6 @@ AnalogAudioView::AnalogAudioView( // Filename Datetime and Frequency record_view.set_filename_date_frequency(true); - field_frequency.set_value(receiver_model.target_frequency()); - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; - field_frequency.on_show_options = [this]() { this->on_show_options_frequency(); }; diff --git a/firmware/application/apps/analog_audio_app.hpp b/firmware/application/apps/analog_audio_app.hpp index 986b3fd65..b76cc0c08 100644 --- a/firmware/application/apps/analog_audio_app.hpp +++ b/firmware/application/apps/analog_audio_app.hpp @@ -26,6 +26,7 @@ #include "receiver_model.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_spectrum.hpp" #include "ui_record_view.hpp" #include "ui_styles.hpp" @@ -156,6 +157,7 @@ class AnalogAudioView : public View { private: static constexpr ui::Dim header_height = 3 * 16; + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_audio", app_settings::Mode::RX, @@ -168,24 +170,20 @@ class AnalogAudioView : public View { uint32_t spec_bw = 20000000; uint16_t spec_trigger = 63; - NavigationView& nav_; // bool exit_on_squelch { false }; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; Audio audio{ - {21 * 8, 10, 6 * 8, 4}, - }; + {21 * 8, 10, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {5 * 8, 0 * 16}, - }; + nav_}; LNAGainField field_lna{ {15 * 8, 0 * 16}}; @@ -229,7 +227,6 @@ class AnalogAudioView : public View { void on_show_options_modulation(); void on_frequency_step_changed(rf::Frequency f); void on_reference_ppm_correction_changed(int32_t v); - void on_edit_frequency(); void remove_options_widget(); void set_options_widget(std::unique_ptr new_widget); diff --git a/firmware/application/apps/analog_tv_app.cpp b/firmware/application/apps/analog_tv_app.cpp index 9ed6b5bce..60feaec11 100644 --- a/firmware/application/apps/analog_tv_app.cpp +++ b/firmware/application/apps/analog_tv_app.cpp @@ -56,22 +56,6 @@ AnalogTvView::AnalogTvView( &field_volume, &tv}); - // Set on_change before initialising the field - field_frequency.on_change = [this](rf::Frequency f) { - this->on_target_frequency_changed(f); - }; - - field_frequency.set_value(receiver_model.target_frequency()); - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->on_target_frequency_changed(f); - this->field_frequency.set_value(f); - }; - }; - field_frequency.on_show_options = [this]() { this->on_show_options_frequency(); }; @@ -125,10 +109,6 @@ void AnalogTvView::focus() { field_frequency.focus(); } -void AnalogTvView::on_target_frequency_changed(rf::Frequency f) { - receiver_model.set_target_frequency(f); -} - void AnalogTvView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) { receiver_model.set_baseband_bandwidth(bandwidth_hz); } diff --git a/firmware/application/apps/analog_tv_app.hpp b/firmware/application/apps/analog_tv_app.hpp index 0ebbccf7a..f4ab49c35 100644 --- a/firmware/application/apps/analog_tv_app.hpp +++ b/firmware/application/apps/analog_tv_app.hpp @@ -27,6 +27,7 @@ #include "receiver_model.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_tv.hpp" #include "ui_record_view.hpp" #include "ui_styles.hpp" @@ -53,6 +54,7 @@ class AnalogTvView : public View { private: static constexpr ui::Dim header_height = 3 * 16; + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_tv", app_settings::Mode::RX}; @@ -60,23 +62,18 @@ class AnalogTvView : public View { const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16}; const Rect nbfm_view_rect{0 * 8, 1 * 16, 18 * 8, 1 * 16}; - NavigationView& nav_; - RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; Audio audio{ - {21 * 8, 10, 6 * 8, 4}, - }; + {21 * 8, 10, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {5 * 8, 0 * 16}, - }; + nav_}; LNAGainField field_lna{ {15 * 8, 0 * 16}}; @@ -100,7 +97,6 @@ class AnalogTvView : public View { tv::TVWidget tv{}; - void on_target_frequency_changed(rf::Frequency f); void on_baseband_bandwidth_changed(uint32_t bandwidth_hz); void on_modulation_changed(const ReceiverModel::Mode modulation); void on_show_options_frequency(); @@ -108,7 +104,6 @@ class AnalogTvView : public View { void on_show_options_modulation(); void on_frequency_step_changed(rf::Frequency f); void on_reference_ppm_correction_changed(int32_t v); - void on_edit_frequency(); void remove_options_widget(); void set_options_widget(std::unique_ptr new_widget); diff --git a/firmware/application/apps/capture_app.cpp b/firmware/application/apps/capture_app.cpp index 20846326b..55cf48ef4 100644 --- a/firmware/application/apps/capture_app.cpp +++ b/firmware/application/apps/capture_app.cpp @@ -28,7 +28,8 @@ using namespace portapack; namespace ui { -CaptureAppView::CaptureAppView(NavigationView& nav) { +CaptureAppView::CaptureAppView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_capture); add_children({ @@ -45,19 +46,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { &waterfall, }); - field_frequency.set_value(receiver_model.target_frequency()); - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->field_frequency.set_value(f); - }; - }; - field_frequency_step.set_by_value(receiver_model.frequency_step()); field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) { receiver_model.set_frequency_step(v); diff --git a/firmware/application/apps/capture_app.hpp b/firmware/application/apps/capture_app.hpp index 6eeeac851..57933cc8b 100644 --- a/firmware/application/apps/capture_app.hpp +++ b/firmware/application/apps/capture_app.hpp @@ -26,6 +26,7 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_record_view.hpp" #include "ui_spectrum.hpp" #include "app_settings.hpp" @@ -64,6 +65,7 @@ class CaptureAppView : public View { private: static constexpr ui::Dim header_height = 3 * 16; + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_capture", app_settings::Mode::RX, @@ -72,27 +74,22 @@ class CaptureAppView : public View { uint32_t sampling_rate = 0; uint32_t anti_alias_baseband_bandwidth_filter = 2500000; - void on_target_frequency_changed(rf::Frequency f); - Labels labels{ {{0 * 8, 1 * 16}, "Rate:", Color::light_grey()}, }; RSSI rssi{ - {24 * 8, 0, 6 * 8, 4}, - }; + {24 * 8, 0, 6 * 8, 4}}; Channel channel{ - {24 * 8, 5, 6 * 8, 4}, - }; + {24 * 8, 5, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 16}, - }; + nav_}; FrequencyStepView field_frequency_step{ - {10 * 8, 0 * 16}, - }; + {10 * 8, 0 * 16}}; RFAmpField field_rf_amp{ {16 * 8, 0 * 16}}; diff --git a/firmware/application/apps/gps_sim_app.cpp b/firmware/application/apps/gps_sim_app.cpp index 332fa70f8..c85614ec9 100644 --- a/firmware/application/apps/gps_sim_app.cpp +++ b/firmware/application/apps/gps_sim_app.cpp @@ -187,18 +187,7 @@ GpsSimAppView::GpsSimAppView( &waterfall, }); - field_frequency.set_value(transmitter_model.target_frequency()); field_frequency.set_step(5000); - field_frequency.on_change = [this](rf::Frequency f) { - transmitter_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(transmitter_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->field_frequency.set_value(f); - }; - }; button_play.on_select = [this](ImageButton&) { this->toggle(); diff --git a/firmware/application/apps/gps_sim_app.hpp b/firmware/application/apps/gps_sim_app.hpp index eff405ef3..8a271959a 100644 --- a/firmware/application/apps/gps_sim_app.hpp +++ b/firmware/application/apps/gps_sim_app.hpp @@ -32,6 +32,7 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "replay_thread.hpp" #include "ui_spectrum.hpp" #include "ui_transmitter.hpp" @@ -102,9 +103,9 @@ class GpsSimAppView : public View { ProgressBar progressbar{ {18 * 8, 1 * 16, 12 * 8, 16}}; - FrequencyField field_frequency{ + TxFrequencyField field_frequency{ {0 * 8, 2 * 16}, - }; + nav_}; TransmitterView2 tx_view{ // new handling of NumberField field_rfgain, NumberField field_rfamp diff --git a/firmware/application/apps/pocsag_app.cpp b/firmware/application/apps/pocsag_app.cpp index 373b0b0e5..869911ccb 100644 --- a/firmware/application/apps/pocsag_app.cpp +++ b/firmware/application/apps/pocsag_app.cpp @@ -51,9 +51,8 @@ void POCSAGLogger::log_decoded( namespace ui { -POCSAGAppView::POCSAGAppView(NavigationView& nav) { - uint32_t ignore_address; - +POCSAGAppView::POCSAGAppView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_pocsag); add_children({&rssi, @@ -70,28 +69,16 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { &console}); if (!settings_.loaded()) - receiver_model.set_target_frequency(initial_target_frequency); + field_frequency.set_value(initial_target_frequency); receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); receiver_model.enable(); - field_frequency.set_value(receiver_model.target_frequency()); - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; - - // TODO app setting instead? + // TODO: app setting instead? + uint32_t ignore_address; ignore_address = persistent_memory::pocsag_ignore_address(); - // TODO is this common enough for a helper? + // TODO: is this common enough for a helper? for (size_t c = 0; c < 7; c++) { sym_ignore.set_sym(6 - c, ignore_address % 10); ignore_address /= 10; @@ -156,9 +143,10 @@ void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) { console.write(console_info); if (logger && logging()) { - logger->log_decoded(message->packet, to_string_dec_uint(pocsag_state.address) + - " F" + to_string_dec_uint(pocsag_state.function) + - " Address only"); + logger->log_decoded( + message->packet, to_string_dec_uint(pocsag_state.address) + + " F" + to_string_dec_uint(pocsag_state.function) + + " Address only"); } last_address = pocsag_state.address; @@ -175,16 +163,17 @@ void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) { } if (logger && logging()) - logger->log_decoded(message->packet, to_string_dec_uint(pocsag_state.address) + - " F" + to_string_dec_uint(pocsag_state.function) + - " Alpha: " + pocsag_state.output); + logger->log_decoded( + message->packet, to_string_dec_uint(pocsag_state.address) + + " F" + to_string_dec_uint(pocsag_state.function) + + " Alpha: " + pocsag_state.output); } } // TODO: make setting. // Log raw data whatever it contains - if (logger && logging()) - logger->log_raw_data(message->packet, receiver_model.target_frequency()); + /*if (logger && logging()) + logger->log_raw_data(message->packet, receiver_model.target_frequency());*/ } } /* namespace ui */ diff --git a/firmware/application/apps/pocsag_app.hpp b/firmware/application/apps/pocsag_app.hpp index 826563738..f43094b67 100644 --- a/firmware/application/apps/pocsag_app.hpp +++ b/firmware/application/apps/pocsag_app.hpp @@ -24,6 +24,7 @@ #define __POCSAG_APP_H__ #include "ui_widget.hpp" +#include "ui_freq_field.hpp" #include "ui_receiver.hpp" #include "ui_rssi.hpp" @@ -61,6 +62,7 @@ class POCSAGAppView : public View { bool logging() const { return check_log.value(); }; bool ignore() const { return check_ignore.value(); }; + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_pocsag", app_settings::Mode::RX}; @@ -75,18 +77,15 @@ class POCSAGAppView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; Audio audio{ - {21 * 8, 10, 6 * 8, 4}, - }; + {21 * 8, 10, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 8}, - }; + nav_}; AudioVolumeField field_volume{ {28 * 8, 0 * 16}}; diff --git a/firmware/application/apps/replay_app.cpp b/firmware/application/apps/replay_app.cpp index 295d547b7..84fcf8831 100644 --- a/firmware/application/apps/replay_app.cpp +++ b/firmware/application/apps/replay_app.cpp @@ -188,27 +188,12 @@ ReplayAppView::ReplayAppView( &text_duration, &progressbar, &field_frequency, - &tx_view, // now it handles previous rfgain , rfamp. + &tx_view, // now it handles previous rfgain, rfamp. &check_loop, &button_play, &waterfall, }); - field_frequency.set_value(transmitter_model.target_frequency()); - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_change = [this](rf::Frequency f) { - transmitter_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(transmitter_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; - - field_frequency.set_step(5000); - button_play.on_select = [this](ImageButton&) { this->toggle(); }; diff --git a/firmware/application/apps/replay_app.hpp b/firmware/application/apps/replay_app.hpp index ce3bd9bac..42362055f 100644 --- a/firmware/application/apps/replay_app.hpp +++ b/firmware/application/apps/replay_app.hpp @@ -31,6 +31,7 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "replay_thread.hpp" #include "ui_spectrum.hpp" #include "ui_transmitter.hpp" @@ -98,9 +99,10 @@ class ReplayAppView : public View { ProgressBar progressbar{ {18 * 8, 1 * 16, 12 * 8, 16}}; - FrequencyField field_frequency{ + // TODO: Does this need to be a frequency field at all? + TxFrequencyField field_frequency{ {0 * 8, 2 * 16}, - }; + nav_}; TransmitterView2 tx_view{ // new handling of NumberField field_rfgain, NumberField field_rfamp diff --git a/firmware/application/apps/ui_afsk_rx.cpp b/firmware/application/apps/ui_afsk_rx.cpp index ac0b2182d..38674ada3 100644 --- a/firmware/application/apps/ui_afsk_rx.cpp +++ b/firmware/application/apps/ui_afsk_rx.cpp @@ -43,11 +43,8 @@ void AFSKRxView::focus() { field_frequency.focus(); } -void AFSKRxView::update_freq(rf::Frequency f) { - receiver_model.set_target_frequency(f); -} - -AFSKRxView::AFSKRxView(NavigationView& nav) { +AFSKRxView::AFSKRxView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_afsk_rx); add_children({&rssi, @@ -62,8 +59,8 @@ AFSKRxView::AFSKRxView(NavigationView& nav) { &button_modem_setup, &console}); - // Auto-configure modem for LCR RX (will be removed later) - update_freq(467225500); // 462713300 + // Auto-configure modem for LCR RX (TODO remove) + field_frequency.set_value(467225500); auto def_bell202 = &modem_defs[0]; persistent_memory::set_modem_baudrate(def_bell202->baudrate); serial_format_t serial_format; @@ -73,17 +70,7 @@ AFSKRxView::AFSKRxView(NavigationView& nav) { serial_format.bit_order = LSB_FIRST; persistent_memory::set_serial_format(serial_format); - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(100); - field_frequency.on_change = [this](rf::Frequency f) { - update_freq(f); - }; - field_frequency.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; check_log.set_value(logging); check_log.on_select = [this](Checkbox&, bool v) { diff --git a/firmware/application/apps/ui_afsk_rx.hpp b/firmware/application/apps/ui_afsk_rx.hpp index cc2635f46..433777e78 100644 --- a/firmware/application/apps/ui_afsk_rx.hpp +++ b/firmware/application/apps/ui_afsk_rx.hpp @@ -26,7 +26,8 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" -#include "ui_record_view.hpp" // DEBUG +#include "ui_freq_field.hpp" +#include "ui_record_view.hpp" #include "app_settings.hpp" #include "radio_state.hpp" #include "log_file.hpp" @@ -58,6 +59,7 @@ class AFSKRxView : public View { private: void on_data(uint32_t value, bool is_data); + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_afsk", app_settings::Mode::RX}; @@ -74,18 +76,16 @@ class AFSKRxView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; AudioVolumeField field_volume{ {28 * 8, 0 * 16}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 16}, - }; + nav_}; Checkbox check_log{ {0 * 8, 1 * 16}, @@ -104,7 +104,6 @@ class AFSKRxView : public View { Console console{ {0, 4 * 16, 240, 240}}; - void update_freq(rf::Frequency f); void on_data_afsk(const AFSKDataMessage& message); std::unique_ptr logger{}; diff --git a/firmware/application/apps/ui_aprs_rx.cpp b/firmware/application/apps/ui_aprs_rx.cpp index afa7b3f54..09d98b94f 100644 --- a/firmware/application/apps/ui_aprs_rx.cpp +++ b/firmware/application/apps/ui_aprs_rx.cpp @@ -73,12 +73,8 @@ void APRSRxView::focus() { options_region.focus(); } -void APRSRxView::update_freq(rf::Frequency f) { - receiver_model.set_target_frequency(f); -} - APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) - : View(parent_rect) { + : View(parent_rect), nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_aprs_rx); add_children({&rssi, @@ -111,18 +107,7 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) } }; - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(100); - field_frequency.on_change = [this](rf::Frequency f) { - update_freq(f); - }; - field_frequency.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; - options_region.set_selected_index(0, true); logger = std::make_unique(); diff --git a/firmware/application/apps/ui_aprs_rx.hpp b/firmware/application/apps/ui_aprs_rx.hpp index bc3b821ed..267f959e1 100644 --- a/firmware/application/apps/ui_aprs_rx.hpp +++ b/firmware/application/apps/ui_aprs_rx.hpp @@ -26,7 +26,8 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" -#include "ui_record_view.hpp" // DEBUG +#include "ui_freq_field.hpp" +#include "ui_record_view.hpp" #include "ui_geomap.hpp" #include "app_settings.hpp" #include "radio_state.hpp" @@ -188,6 +189,7 @@ class APRSRxView : public View { void on_data(uint32_t value, bool is_data); bool reset_console = false; + NavigationView& nav_; RxRadioState radio_state_{}; app_settings::SettingsManager settings_{ "rx_aprs", app_settings::Mode::RX}; @@ -202,11 +204,9 @@ class APRSRxView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; AudioVolumeField field_volume{ {28 * 8, 0 * 16}}; @@ -219,9 +219,9 @@ class APRSRxView : public View { {"AUS", 2}, {"NZ ", 3}}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {3 * 8, 0 * 16}, - }; + nav_}; // DEBUG RecordView record_view{ @@ -235,8 +235,6 @@ class APRSRxView : public View { Console console{ {0, 2 * 16, 240, 240}}; - void update_freq(rf::Frequency f); - std::unique_ptr logger{}; }; diff --git a/firmware/application/apps/ui_btle_rx.cpp b/firmware/application/apps/ui_btle_rx.cpp index 49fe1c92a..bdf5601f5 100644 --- a/firmware/application/apps/ui_btle_rx.cpp +++ b/firmware/application/apps/ui_btle_rx.cpp @@ -40,11 +40,8 @@ void BTLERxView::focus() { field_frequency.focus(); } -void BTLERxView::update_freq(rf::Frequency f) { - receiver_model.set_target_frequency(f); -} - -BTLERxView::BTLERxView(NavigationView& nav) { +BTLERxView::BTLERxView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_btle_rx); add_children({&rssi, @@ -56,8 +53,8 @@ BTLERxView::BTLERxView(NavigationView& nav) { &button_modem_setup, &console}); - // Auto-configure modem for LCR RX (will be removed later) - update_freq(2426000000); + // Auto-configure modem for LCR RX (TODO: remove later) + field_frequency.set_value(2426000000); auto def_bell202 = &modem_defs[0]; persistent_memory::set_modem_baudrate(def_bell202->baudrate); serial_format_t serial_format; @@ -67,17 +64,7 @@ BTLERxView::BTLERxView(NavigationView& nav) { serial_format.bit_order = LSB_FIRST; persistent_memory::set_serial_format(serial_format); - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(100); - field_frequency.on_change = [this](rf::Frequency f) { - update_freq(f); - }; - field_frequency.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; button_modem_setup.on_select = [&nav](Button&) { nav.push(); diff --git a/firmware/application/apps/ui_btle_rx.hpp b/firmware/application/apps/ui_btle_rx.hpp index 86afa348c..0acb543f5 100644 --- a/firmware/application/apps/ui_btle_rx.hpp +++ b/firmware/application/apps/ui_btle_rx.hpp @@ -27,9 +27,10 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "app_settings.hpp" #include "radio_state.hpp" -#include "ui_record_view.hpp" // DEBUG +#include "ui_record_view.hpp" #include "utility.hpp" @@ -47,6 +48,7 @@ class BTLERxView : public View { private: void on_data(uint32_t value, bool is_data); + NavigationView& nav_; RxRadioState radio_state_{ 4000000 /* bandwidth */, 4000000 /* sampling rate */ @@ -64,15 +66,13 @@ class BTLERxView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 16}, - }; + nav_}; Button button_modem_setup{ {240 - 12 * 8, 1 * 16, 96, 24}, @@ -81,9 +81,6 @@ class BTLERxView : public View { Console console{ {0, 4 * 16, 240, 240}}; - void update_freq(rf::Frequency f); - // void on_data_afsk(const AFSKDataMessage& message); - MessageHandlerRegistration message_handler_packet{ Message::ID::AFSKData, [this](Message* const p) { diff --git a/firmware/application/apps/ui_mictx.hpp b/firmware/application/apps/ui_mictx.hpp index 8599e8cb0..0cbb6f285 100644 --- a/firmware/application/apps/ui_mictx.hpp +++ b/firmware/application/apps/ui_mictx.hpp @@ -204,6 +204,7 @@ class MicTXView : public View { {"OFF-08dB", 4}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -12 dB's (respect ref level) }}; + // TODO: Use TxFrequencyField FrequencyField field_frequency{ {5 * 8, 3 * 8}, }; @@ -309,6 +310,7 @@ class MicTXView : public View { ' ', }; + // TODO: Use RxFrequencyField FrequencyField field_rxfrequency{ {10 * 8, (25 * 8) + 2}, }; diff --git a/firmware/application/apps/ui_modemsetup.hpp b/firmware/application/apps/ui_modemsetup.hpp index 534252eb2..efa25c8a9 100644 --- a/firmware/application/apps/ui_modemsetup.hpp +++ b/firmware/application/apps/ui_modemsetup.hpp @@ -38,8 +38,6 @@ class ModemSetupView : public View { std::string title() const override { return "Modem setup"; }; private: - void update_freq(rf::Frequency f); - Labels labels{ {{2 * 8, 11 * 8}, "Baudrate:", Color::light_grey()}, {{2 * 8, 13 * 8}, "Mark: Hz", Color::light_grey()}, diff --git a/firmware/application/apps/ui_nrf_rx.cpp b/firmware/application/apps/ui_nrf_rx.cpp index c719e594e..e07135a5a 100644 --- a/firmware/application/apps/ui_nrf_rx.cpp +++ b/firmware/application/apps/ui_nrf_rx.cpp @@ -40,11 +40,8 @@ void NRFRxView::focus() { field_frequency.focus(); } -void NRFRxView::update_freq(rf::Frequency f) { - receiver_model.set_target_frequency(f); -} - -NRFRxView::NRFRxView(NavigationView& nav) { +NRFRxView::NRFRxView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_nrf_rx); add_children({&rssi, @@ -57,7 +54,7 @@ NRFRxView::NRFRxView(NavigationView& nav) { &console}); // Auto-configure modem for LCR RX (will be removed later) - update_freq(2480000000); + field_frequency.set_value(2480000000); auto def_bell202 = &modem_defs[0]; persistent_memory::set_modem_baudrate(def_bell202->baudrate); serial_format_t serial_format; @@ -67,17 +64,7 @@ NRFRxView::NRFRxView(NavigationView& nav) { serial_format.bit_order = LSB_FIRST; persistent_memory::set_serial_format(serial_format); - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(100); - field_frequency.on_change = [this](rf::Frequency f) { - update_freq(f); - }; - field_frequency.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; button_modem_setup.on_select = [&nav](Button&) { nav.push(); diff --git a/firmware/application/apps/ui_nrf_rx.hpp b/firmware/application/apps/ui_nrf_rx.hpp index 2eebe088e..7ffa3613f 100644 --- a/firmware/application/apps/ui_nrf_rx.hpp +++ b/firmware/application/apps/ui_nrf_rx.hpp @@ -27,6 +27,7 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "app_settings.hpp" #include "radio_state.hpp" #include "ui_record_view.hpp" // DEBUG @@ -47,6 +48,7 @@ class NRFRxView : public View { private: void on_data(uint32_t value, bool is_data); + NavigationView& nav_; RxRadioState radio_state_{ 4000000 /* bandwidth */, 4000000 /* sampling rate */ @@ -64,15 +66,13 @@ class NRFRxView : public View { VGAGainField field_vga{ {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; Channel channel{ - {21 * 8, 5, 6 * 8, 4}, - }; + {21 * 8, 5, 6 * 8, 4}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 16}, - }; + nav_}; Button button_modem_setup{ {240 - 12 * 8, 1 * 16, 96, 24}, @@ -81,9 +81,6 @@ class NRFRxView : public View { Console console{ {0, 4 * 16, 240, 240}}; - void update_freq(rf::Frequency f); - // void on_data_afsk(const AFSKDataMessage& message); - MessageHandlerRegistration message_handler_packet{ Message::ID::AFSKData, [this](Message* const p) { diff --git a/firmware/application/apps/ui_search.cpp b/firmware/application/apps/ui_search.cpp index 14a6a5dc0..8bb887247 100644 --- a/firmware/application/apps/ui_search.cpp +++ b/firmware/application/apps/ui_search.cpp @@ -378,26 +378,14 @@ SearchView::SearchView( field_frequency_min.set_value(receiver_model.target_frequency() - 1000000); field_frequency_min.set_step(100000); - field_frequency_min.on_change = [this](rf::Frequency) { - this->on_range_changed(); - }; - field_frequency_min.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->field_frequency_min.set_value(f); - }; + field_frequency_min.updated = [this](rf::Frequency) { + on_range_changed(); }; field_frequency_max.set_value(receiver_model.target_frequency() + 1000000); field_frequency_max.set_step(100000); - field_frequency_max.on_change = [this](rf::Frequency) { - this->on_range_changed(); - }; - field_frequency_max.on_edit = [this, &nav]() { - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->field_frequency_max.set_value(f); - }; + field_frequency_max.updated = [this](rf::Frequency) { + on_range_changed(); }; field_lna.set_value(receiver_model.lna()); diff --git a/firmware/application/apps/ui_search.hpp b/firmware/application/apps/ui_search.hpp index e93b2f319..77826fac2 100644 --- a/firmware/application/apps/ui_search.hpp +++ b/firmware/application/apps/ui_search.hpp @@ -26,6 +26,7 @@ #include "spectrum_color_lut.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_styles.hpp" #include "recent_entries.hpp" @@ -146,12 +147,14 @@ class SearchView : public View { {{1 * 8, 25 * 8}, "Accuracy +/-4.9kHz", Color::light_grey()}, {{26 * 8, 25 * 8}, "MHz", Color::light_grey()}}; - FrequencyField field_frequency_min{ + RxFrequencyField field_frequency_min{ {1 * 8, 1 * 16}, - }; - FrequencyField field_frequency_max{ + nav_, + false}; + RxFrequencyField field_frequency_max{ {11 * 8, 1 * 16}, - }; + nav_, + false}; LNAGainField field_lna{ {22 * 8, 1 * 16}}; VGAGainField field_vga{ diff --git a/firmware/application/apps/ui_sonde.cpp b/firmware/application/apps/ui_sonde.cpp index 04d9d4885..66be44a7e 100644 --- a/firmware/application/apps/ui_sonde.cpp +++ b/firmware/application/apps/ui_sonde.cpp @@ -41,7 +41,8 @@ void SondeLogger::on_packet(const sonde::Packet& packet) { namespace ui { -SondeView::SondeView(NavigationView& nav) { +SondeView::SondeView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_sonde); add_children({&labels, @@ -66,20 +67,9 @@ SondeView::SondeView(NavigationView& nav) { &button_see_map}); if (!settings_.loaded()) - receiver_model.set_target_frequency(initial_target_frequency); + field_frequency.set_value(initial_target_frequency); - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(500); // euquiq: was 10000, but we are using this for fine-tunning - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; geopos.set_read_only(true); diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index 2c4fada49..4053067e8 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -25,6 +25,7 @@ #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_rssi.hpp" #include "ui_qrcode.hpp" #include "ui_geomap.hpp" @@ -65,6 +66,7 @@ class SondeView : public View { std::string title() const override { return "Radiosnd RX"; }; private: + NavigationView& nav_; RxRadioState radio_state_{ 1750000 /* bandwidth */, 2457600 /* sampling rate */ @@ -96,9 +98,9 @@ class SondeView : public View { {{4 * 8, 7 * 16}, "Temp:", Color::light_grey()}, {{0 * 8, 8 * 16}, "Humidity:", Color::light_grey()}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 8}, - }; + nav_}; RFAmpField field_rf_amp{ {13 * 8, 0 * 16}}; @@ -110,8 +112,7 @@ class SondeView : public View { {18 * 8, 0 * 16}}; RSSI rssi{ - {21 * 8, 0, 6 * 8, 4}, - }; + {21 * 8, 0, 6 * 8, 4}}; AudioVolumeField field_volume{ {28 * 8, 0 * 16}}; diff --git a/firmware/application/apps/ui_spectrum_painter.cpp b/firmware/application/apps/ui_spectrum_painter.cpp index 97385d867..9d904b26f 100644 --- a/firmware/application/apps/ui_spectrum_painter.cpp +++ b/firmware/application/apps/ui_spectrum_painter.cpp @@ -57,17 +57,7 @@ SpectrumPainterView::SpectrumPainterView( input_image.set_parent_rect(view_rect); input_text.set_parent_rect(view_rect); - field_frequency.set_value(transmitter_model.target_frequency()); field_frequency.set_step(5000); - field_frequency.on_change = [this](rf::Frequency f) { - transmitter_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - auto new_view = nav.push(transmitter_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; tx_gain = transmitter_model.tx_gain(); field_rfgain.set_value(tx_gain); // Initial default value (-12 dB's max ). diff --git a/firmware/application/apps/ui_spectrum_painter.hpp b/firmware/application/apps/ui_spectrum_painter.hpp index e52bea277..fb6cb1fe3 100644 --- a/firmware/application/apps/ui_spectrum_painter.hpp +++ b/firmware/application/apps/ui_spectrum_painter.hpp @@ -94,9 +94,9 @@ class SpectrumPainterView : public View { {{1 * 8, footer_location + 2 * 16}, "BW: Du: P:", Color::light_grey()}, }; - FrequencyField field_frequency{ + TxFrequencyField field_frequency{ {0 * 8, footer_location + 1 * 16}, - }; + nav_}; NumberField field_rfgain{ {14 * 8, footer_location + 1 * 16}, diff --git a/firmware/application/apps/ui_test.cpp b/firmware/application/apps/ui_test.cpp index a51841fdc..1029ac866 100644 --- a/firmware/application/apps/ui_test.cpp +++ b/firmware/application/apps/ui_test.cpp @@ -40,7 +40,8 @@ void TestLogger::log_raw_data(const testapp::Packet& packet, const int32_t alt) namespace ui { -TestView::TestView(NavigationView& nav) { +TestView::TestView(NavigationView& nav) + : nav_{nav} { baseband::run_image(portapack::spi_flash::image_tag_test); add_children({&labels, @@ -54,18 +55,7 @@ TestView::TestView(NavigationView& nav) { &button_cal, &check_log}); - field_frequency.set_value(receiver_model.target_frequency()); field_frequency.set_step(10000); - field_frequency.on_change = [this](rf::Frequency f) { - receiver_model.set_target_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(receiver_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - field_frequency.set_value(f); - }; - }; check_log.on_select = [this](Checkbox&, bool v) { logging = v; diff --git a/firmware/application/apps/ui_test.hpp b/firmware/application/apps/ui_test.hpp index bd6d5d60c..ec439f180 100644 --- a/firmware/application/apps/ui_test.hpp +++ b/firmware/application/apps/ui_test.hpp @@ -25,6 +25,7 @@ #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_rssi.hpp" #include "event_m0.hpp" @@ -59,6 +60,7 @@ class TestView : public View { std::string title() const override { return "Test app"; }; private: + NavigationView& nav_; RxRadioState radio_state_{ 1750000 /* bandwidth */, 2457600 * 2 /* sampling rate */ @@ -75,9 +77,9 @@ class TestView : public View { Labels labels{ {{0 * 8, 1 * 16}, "Data:", Color::light_grey()}}; - FrequencyField field_frequency{ + RxFrequencyField field_frequency{ {0 * 8, 0 * 8}, - }; + nav_}; RFAmpField field_rf_amp{ {13 * 8, 0 * 16}}; diff --git a/firmware/application/apps/ui_whipcalc.cpp b/firmware/application/apps/ui_whipcalc.cpp index 68c605758..7211940c7 100644 --- a/firmware/application/apps/ui_whipcalc.cpp +++ b/firmware/application/apps/ui_whipcalc.cpp @@ -102,7 +102,8 @@ void WhipCalcView::update_result() { } } -WhipCalcView::WhipCalcView(NavigationView& nav) { +WhipCalcView::WhipCalcView(NavigationView& nav) + : nav_{nav} { add_children({&labels, //&antennas_on_memory, &field_frequency, @@ -142,16 +143,8 @@ WhipCalcView::WhipCalcView(NavigationView& nav) { }; field_frequency.set_step(1000000); // 1MHz step - field_frequency.on_change = [this](rf::Frequency) { - this->update_result(); - }; - field_frequency.on_edit = [this, &nav]() { - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(transmitter_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - this->field_frequency.set_value(f); - this->update_result(); - }; + field_frequency.updated = [this](rf::Frequency) { + update_result(); }; button_exit.on_select = [this, &nav](Button&) { diff --git a/firmware/application/apps/ui_whipcalc.hpp b/firmware/application/apps/ui_whipcalc.hpp index 26380bc17..677ee730c 100644 --- a/firmware/application/apps/ui_whipcalc.hpp +++ b/firmware/application/apps/ui_whipcalc.hpp @@ -26,6 +26,7 @@ #include "ui.hpp" #include "ui_widget.hpp" #include "ui_receiver.hpp" +#include "ui_freq_field.hpp" #include "ui_navigation.hpp" #include "string_format.hpp" #include @@ -47,6 +48,7 @@ class WhipCalcView : public View { std::vector elements{}; }; + NavigationView& nav_; std::vector antenna_db{}; void update_result(); uint16_t string_to_number(std::string); @@ -59,9 +61,10 @@ class WhipCalcView : public View { {{5 * 8, 3 * 16}, "Metric:", Color::light_grey()}, {{3 * 8, 4 * 16}, "Imperial:", Color::light_grey()}}; - FrequencyField field_frequency{ + TxFrequencyField field_frequency{ {13 * 8, 1 * 16}, - }; + nav_, + false}; OptionsField options_type{ {13 * 8, 2 * 16}, diff --git a/firmware/application/ui/ui_freq_field.hpp b/firmware/application/ui/ui_freq_field.hpp new file mode 100644 index 000000000..2c7e5f7fd --- /dev/null +++ b/firmware/application/ui/ui_freq_field.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Kyle Reed + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __UI_FREQ_FIELD_H__ +#define __UI_FREQ_FIELD_H__ + +#include "portapack.hpp" +#include "receiver_model.hpp" +#include "transmitter_model.hpp" +#include "ui_receiver.hpp" + +namespace ui { + +/* A frequency field bound directly a radio model + * that can manage its own editing UX. */ +template +class BoundFrequencyField : public FrequencyField { + private: + using FrequencyField::on_change; + using FrequencyField::on_edit; + + public: + decltype(FrequencyField::on_change) updated{}; + + BoundFrequencyField(Point parent_pos, NavigationView& nav, bool update_model = true) + : FrequencyField(parent_pos) { + // NB: There is no frequency_step on the tx_model. + set_step(portapack::receiver_model.frequency_step()); + set_value(model->target_frequency()); + + on_change = [this, update_model](rf::Frequency f) { + if (update_model) + model->set_target_frequency(f); + if (updated) + updated(f); + }; + + on_edit = [this, &nav]() { + auto freq_view = nav.push(model->target_frequency()); + freq_view->on_changed = [this](rf::Frequency f) { + set_value(f); + }; + }; + } + + // TODO: override set_step and update the rx model then call base. +}; + +using RxFrequencyField = BoundFrequencyField; +using TxFrequencyField = BoundFrequencyField; + +} // namespace ui + +#endif // __UI_FREQ_FIELD_H__ \ No newline at end of file diff --git a/firmware/application/ui/ui_receiver.hpp b/firmware/application/ui/ui_receiver.hpp index b331cab9d..8627fb427 100644 --- a/firmware/application/ui/ui_receiver.hpp +++ b/firmware/application/ui/ui_receiver.hpp @@ -36,7 +36,6 @@ namespace ui { -// TODO: build in support for editing. class FrequencyField : public Widget { public: std::function on_change{}; @@ -45,7 +44,7 @@ class FrequencyField : public Widget { using range_t = rf::FrequencyRange; - FrequencyField(const Point parent_pos); + FrequencyField(Point parent_pos); rf::Frequency value() const; @@ -54,9 +53,9 @@ class FrequencyField : public Widget { void paint(Painter& painter) override; - bool on_key(const ui::KeyEvent event) override; - bool on_encoder(const EncoderEvent delta) override; - bool on_touch(const TouchEvent event) override; + bool on_key(ui::KeyEvent event) override; + bool on_encoder(EncoderEvent delta) override; + bool on_touch(TouchEvent event) override; void on_focus() override; private: