diff --git a/firmware/application/apps/ui_level.cpp b/firmware/application/apps/ui_level.cpp index 2c5e2a424..51cb98cc2 100644 --- a/firmware/application/apps/ui_level.cpp +++ b/firmware/application/apps/ui_level.cpp @@ -215,7 +215,7 @@ namespace ui { last_min_rssi = rssi.get_min(); last_avg_rssi = rssi.get_avg(); last_max_rssi = rssi.get_max(); - freq_stats_rssi.set( "RSSI: "+to_string_dec_int( rssi.get_min() )+"/"+to_string_dec_int( rssi.get_avg() )+"/"+to_string_dec_int( rssi.get_max() )+" db" ); + freq_stats_rssi.set( "RSSI: "+to_string_dec_int( rssi.get_min() )+"/"+to_string_dec_int( rssi.get_avg() )+"/"+to_string_dec_int( rssi.get_max() )+" db, dt: "+to_string_dec_int( rssi.get_delta() )+" db" ); } } /* on_statistic_updates */ diff --git a/firmware/application/apps/ui_level.hpp b/firmware/application/apps/ui_level.hpp index 25473e4db..e4c573bdf 100644 --- a/firmware/application/apps/ui_level.hpp +++ b/firmware/application/apps/ui_level.hpp @@ -47,10 +47,8 @@ namespace ui { ~LevelView(); void focus() override; - - void big_display_freq( int64_t f ); - void on_audio_spectrum(const AudioSpectrum* spectrum); + void big_display_freq( int64_t f ); const Style style_grey { // level .font = font::fixed_8x16, @@ -143,18 +141,18 @@ namespace ui { }; OptionsField step_mode { - { 21 * 8, 1 * 16 }, + { 16 * 8, 2 * 16 + 4 }, 12, { } }; - + RSSIGraph rssi_graph { // 240x320 => - { 0 , 5 * 16 + 4 , 240 - 5 * 8 , 320 - 5 * 16 - 4 }, + { 0 , 5 * 16 + 4 , 240 - 5 * 8 , 216 }, }; - RSSI rssi { // 240x320 => - { 240 - 5 * 8 , 5 * 16 + 4 , 5 * 8 , 320 - 5 * 16 - 4 }, + RSSI rssi { // 240x320 => + { 240 - 5 * 8 , 5 * 16 + 4 , 5 * 8 , 216 }, }; @@ -164,7 +162,7 @@ namespace ui { }; OptionsField audio_mode { - { 16 * 8, 2 * 16 + 4 }, + { 21 * 8, 1 * 16 }, 9, { {"audio off", 0}, @@ -188,7 +186,7 @@ namespace ui { { 0 * 8 , 4 * 16 + 4 , 15 * 8, 16 }, }; - + OptionsField peak_mode { { 44 + 10 * 8, 4 * 16 + 4 }, 10, diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index df93a8195..33e4c9371 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -20,6 +20,9 @@ * Boston, MA 02110-1301, USA. */ +#ifndef _UI_GLASS +#define _UI_GLASS + #include "ui.hpp" #include "portapack.hpp" #include "baseband_api.hpp" @@ -184,4 +187,4 @@ }; } - +#endif diff --git a/firmware/application/apps/ui_recon.cpp b/firmware/application/apps/ui_recon.cpp index 9f185e94f..3b05a147e 100644 --- a/firmware/application/apps/ui_recon.cpp +++ b/firmware/application/apps/ui_recon.cpp @@ -524,15 +524,21 @@ namespace ui { if(frequency_list[index].description.size() > 0) desc_cycle.set( frequency_list[index].description ); //Show new description } big_display.set_style(&style_white); + if( !userpause ) + button_pause.set_text(""); + else + button_pause.set_text(""); } else if( freq_lock == 1 && recon_lock_nb_match != 1 ) { //STARTING LOCK FREQ big_display.set_style(&style_yellow); + button_pause.set_text(""); } else if( index < 1000 && freq_lock >= recon_thread -> get_lock_nb_match() ) { big_display.set_style( &style_green); + button_pause.set_text(""); //FREQ IS STRONG: GREEN and recon will pause when on_statistics_update() if( (!scanner_mode) && autosave && last_freq != freq ) { @@ -660,6 +666,7 @@ namespace ui { &field_lock_wait, &button_recon_setup, &button_scanner_mode, + &button_looking_glass, &file_name, &rssi, &text_cycle, @@ -875,6 +882,20 @@ namespace ui { nav_.push(); }; + button_looking_glass.on_select = [this](Button&) { + recon_thread->stop(); + nav_.pop(); + nav_.push(); + }; + + + rssi.set_focusable(true); + rssi.on_select = [this](RSSI&) { + recon_thread->stop(); + nav_.pop(); + nav_.push(); + }; + button_mic_app.on_select = [this](Button&) { recon_thread->stop(); nav_.pop(); @@ -1091,7 +1112,7 @@ namespace ui { show_max(); /* display step information */ text_cycle.set( "MANUAL SEARCH" ); button_scanner_mode.set_style( &style_white ); - button_scanner_mode.set_text( "M-SEARCH" ); + button_scanner_mode.set_text( "MSEARCH" ); file_name.set_style( &style_white ); file_name.set( "USE: MANUAL RANGE" ); @@ -1653,7 +1674,7 @@ namespace ui { void ReconView::user_pause() { timer = 0 ; // Will trigger a recon_resume() on_statistics_update, also advancing to next freq. - button_pause.set_text(""); //PAUSED, show resume + //button_pause.set_text(""); //PAUSED, show resume userpause=true; continuous_lock=false; recon_pause(); @@ -1661,7 +1682,7 @@ namespace ui { void ReconView::user_resume() { timer = 0 ; // Will trigger a recon_resume() on_statistics_update, also advancing to next freq. - button_pause.set_text(""); //Show button for pause + //button_pause.set_text(""); //Show button for pause userpause=false; // Resume recon continuous_lock=false; recon_resume(); diff --git a/firmware/application/apps/ui_recon.hpp b/firmware/application/apps/ui_recon.hpp index 1bfaf6e0c..0fd4b5ce2 100644 --- a/firmware/application/apps/ui_recon.hpp +++ b/firmware/application/apps/ui_recon.hpp @@ -31,6 +31,8 @@ #include "analog_audio_app.hpp" #include "audio.hpp" #include "ui_mictx.hpp" +#include "ui_level.hpp" +#include "ui_looking_glass_app.hpp" #include "portapack_persistent_memory.hpp" #include "baseband_api.hpp" #include "string_format.hpp" @@ -264,7 +266,7 @@ namespace ui { }; RSSI rssi { - { 0 * 16, 2 * 16, 15 * 16, 8 }, + { 0 * 16, 2 * 16, 240 - 4 * 8 , 16 }, }; Text text_cycle { @@ -276,7 +278,7 @@ namespace ui { }; Text desc_cycle { - {0, 4 * 16, 240, 16 }, + {0, 4 * 16, 240 , 16 }, }; /* BigFrequency big_display { //Show frequency in glamour @@ -285,32 +287,36 @@ namespace ui { }; */ Text big_display { //Show frequency in text mode - { 0, 5 * 16 , 28 * 8, 16 }, + { 0, 5 * 16 , 21 * 8, 16 }, }; Text freq_stats { //Show frequency stats in text mode - { 0, 6 * 16 , 28 * 8, 16 }, + { 0, 6 * 16 , 21 * 8, 16 }, }; Text text_timer { //Show frequency stats in text mode - { 0, 7 * 16 , 28 * 8, 16 }, + { 0, 7 * 16 , 21 * 8, 16 }, }; Button button_recon_setup { - { 25 * 8 , 2 * 16 + 8 , 4 * 8, 28 }, + { 240 - 4 * 8 , 2 * 16 , 4 * 8, 28 }, "OPT" }; + Button button_looking_glass { + { 240 - 5 * 8 , 6 * 16 - 4 , 5 * 8, 28 }, + "GLASS" + }; + Button button_scanner_mode { - { 21 * 8 , 8 * 16 , 9 * 8, 28 }, + { 240 - 8 * 8 , 8 * 16 , 8 * 8, 28 }, "RECON" }; Text file_name { //Show file used - { 0 , 8 * 16 + 4 , 20 * 8, 16 }, + { 0 , 8 * 16 + 6 , 21 * 8, 16 }, }; - ButtonWithEncoder button_manual_start { { 0 * 8, 11 * 16, 11 * 8, 28 }, "" diff --git a/firmware/application/freqman.cpp b/firmware/application/freqman.cpp index 467782e34..413388c3c 100644 --- a/firmware/application/freqman.cpp +++ b/firmware/application/freqman.cpp @@ -51,6 +51,8 @@ options_t freqman_entry_bandwidths[ 4 ] = { }; options_t freqman_entry_steps = { + { "0.1KHz " , 100 }, + { "1KHz " , 1000 }, { "5KHz (SA AM)" , 5000 }, { "6.25KHz(NFM)" , 6250 }, { "8.33KHz(AIR)" , 8330 }, @@ -68,6 +70,8 @@ options_t freqman_entry_steps = { }; options_t freqman_entry_steps_short = { + { "0.1KHz" , 100 }, + { "1KHz" , 1000 }, { "5KHz" , 5000 }, { "6.25KHz" , 6250 }, { "8.33KHz" , 8330 }, diff --git a/firmware/application/ui/ui_rssi.cpp b/firmware/application/ui/ui_rssi.cpp index 674279dac..8721c7151 100644 --- a/firmware/application/ui/ui_rssi.cpp +++ b/firmware/application/ui/ui_rssi.cpp @@ -32,14 +32,23 @@ namespace ui { + RSSI::RSSI( + Rect parent_rect, + bool instant_exec + ) : Widget { parent_rect }, + instant_exec_ { instant_exec } + { + } + void RSSI::paint(Painter& painter) { const auto r = screen_rect(); constexpr int rssi_sample_range = 256; - constexpr float rssi_voltage_min = 0.4; + //constexpr float rssi_voltage_min = 0.4; constexpr float rssi_voltage_max = 2.2; constexpr float adc_voltage_max = 3.3; - constexpr int raw_min = rssi_sample_range * rssi_voltage_min / adc_voltage_max; + //constexpr int raw_min = rssi_sample_range * rssi_voltage_min / adc_voltage_max; + constexpr int raw_min = 0 ; constexpr int raw_max = rssi_sample_range * rssi_voltage_max / adc_voltage_max; constexpr int raw_delta = raw_max - raw_min; @@ -161,6 +170,14 @@ namespace ui { if (pitch_rssi_enabled) { baseband::set_pitch_rssi((avg_ - raw_min) * 2000 / raw_delta, true); } + if( has_focus() || highlighted() ) + { + const Rect r6 { r.left(), r.top(), r.width(), r.height() }; + painter.draw_rectangle( + r6, + Color::white() + ); + } } int32_t RSSI::get_min() @@ -178,6 +195,12 @@ namespace ui { return max_ ; } + int32_t RSSI::get_delta() + { + return max_ - min_ ; + } + + void RSSI::set_pitch_rssi(bool enabled) { pitch_rssi_enabled = enabled; if (!enabled) baseband::set_pitch_rssi(0, false); @@ -272,7 +295,7 @@ namespace ui { painter.draw_vline( p4, width_y, - Color::green()); + Color::green() ); } } @@ -281,10 +304,11 @@ namespace ui { const auto r = screen_rect(); constexpr int rssi_sample_range = 256; - constexpr float rssi_voltage_min = 0.4; + //constexpr float rssi_voltage_min = 0.4; constexpr float rssi_voltage_max = 2.2; constexpr float adc_voltage_max = 3.3; - constexpr int raw_min = rssi_sample_range * rssi_voltage_min / adc_voltage_max; + //constexpr int raw_min = rssi_sample_range * rssi_voltage_min / adc_voltage_max; + constexpr int raw_min = 0 ; constexpr int raw_max = rssi_sample_range * rssi_voltage_max / adc_voltage_max; constexpr int raw_delta = raw_max - raw_min; @@ -308,4 +332,50 @@ namespace ui { } set_dirty(); } + + void RSSI::on_focus() { + if( on_highlight ) + on_highlight(*this); + } + + bool RSSI::on_key(const KeyEvent key) { + if( key == KeyEvent::Select ) { + if( on_select ) { + on_select(*this); + return true; + } + } else { + if( on_dir ) { + return on_dir(*this, key); + } + } + return false; + } + + bool RSSI::on_touch(const TouchEvent event) { + switch(event.type) { + case TouchEvent::Type::Start: + set_highlighted(true); + set_dirty(); + if( on_touch_press) { + on_touch_press(*this); + } + if( on_select && instant_exec_ ) { + on_select(*this); + } + return true; + case TouchEvent::Type::End: + set_highlighted(false); + set_dirty(); + if( on_touch_release) { + on_touch_release(*this); + } + if( on_select && !instant_exec_ ) { + on_select(*this); + } + return true; + default: + return false; + } + } } /* namespace ui */ diff --git a/firmware/application/ui/ui_rssi.hpp b/firmware/application/ui/ui_rssi.hpp index f7783529d..d4adf6ce5 100644 --- a/firmware/application/ui/ui_rssi.hpp +++ b/firmware/application/ui/ui_rssi.hpp @@ -25,87 +25,99 @@ #include "ui.hpp" #include "ui_widget.hpp" #include "ui_painter.hpp" - #include "event_m0.hpp" - #include "message.hpp" - #include namespace ui { -class RSSI : public Widget { -public: - RSSI( - const Rect parent_rect - ) : Widget { parent_rect }, - min_ { 0 }, - avg_ { 0 }, - max_ { 0 } - { - } + class RSSI : public Widget { + public: + std::function on_select { }; + std::function on_touch_release { }; // Executed when releasing touch, after on_select. + std::function on_touch_press { }; // Executed when touching, before on_select. + std::function on_dir { }; + std::function on_highlight { }; - void paint(Painter& painter) override; - int32_t get_min(); - int32_t get_avg(); - int32_t get_max(); - void set_vertical_rssi(bool enabled); - void set_peak(bool enabled, size_t duration); - -private: - int32_t min_; - int32_t avg_; - int32_t max_; - int32_t peak_ = 0 ; - size_t peak_duration_ = 0 ; - - bool pitch_rssi_enabled = false; - bool vertical_rssi_enabled = false; // scale [vertically/from bottom to top] - // instead of [horizontally/from left to right] - bool peak_enabled = false; - size_t peak_duration = 1000; // peak duration in msec before being reset to actual max_rssi + RSSI(Rect parent_rect, bool instant_exec); // instant_exec: Execute on_select when you touching instead of releasing + RSSI( + Rect parent_rect + ) : RSSI { parent_rect, false } + { + } - MessageHandlerRegistration message_handler_stats { - Message::ID::RSSIStatistics, - [this](const Message* const p) { - this->on_statistics_update(static_cast(p)->statistics); - } - }; - - MessageHandlerRegistration message_handler_pitch_rssi { - Message::ID::PitchRSSIConfigure, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->set_pitch_rssi(message.enabled); - } - }; + RSSI( + ) : RSSI { { }, { } } + { + } - void on_statistics_update(const RSSIStatistics& statistics); - void set_pitch_rssi(bool enabled); -}; + int32_t get_min(); + int32_t get_avg(); + int32_t get_max(); + int32_t get_delta(); + void set_vertical_rssi(bool enabled); + void set_peak(bool enabled, size_t duration); -struct RSSIGraph_entry { - int32_t rssi_min { 0 }; - int32_t rssi_avg { 0 }; - int32_t rssi_max { 0 }; - int32_t db { 0 }; -}; + void paint(Painter& painter) override; + void on_focus() override; + bool on_key(const KeyEvent key) override; + bool on_touch(const TouchEvent event) override; -using RSSIGraphList = std::vector; + private: + int32_t min_ = 0; + int32_t avg_ = 0; + int32_t max_ = 0; + int32_t peak_ = 0 ; + size_t peak_duration_ = 0 ; + bool instant_exec_ { false }; -class RSSIGraph : public Widget { -public: - RSSIGraph( - const Rect parent_rect - ) : Widget { parent_rect } - { - } - void paint(Painter& painter) override; - void add_values(int32_t rssi_min, int32_t rssi_avg, int32_t rssi_max, int32_t db ); - -private: - RSSIGraphList graph_list { } ; -}; + bool pitch_rssi_enabled = false; + bool vertical_rssi_enabled = false; // scale [vertically/from bottom to top] + // instead of [horizontally/from left to right] + bool peak_enabled = false; + size_t peak_duration = 1000; // peak duration in msec before being reset to actual max_rssi + + MessageHandlerRegistration message_handler_stats { + Message::ID::RSSIStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + } + }; + + MessageHandlerRegistration message_handler_pitch_rssi { + Message::ID::PitchRSSIConfigure, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->set_pitch_rssi(message.enabled); + } + }; + + void on_statistics_update(const RSSIStatistics& statistics); + void set_pitch_rssi(bool enabled); + }; + + struct RSSIGraph_entry { + int32_t rssi_min { 0 }; + int32_t rssi_avg { 0 }; + int32_t rssi_max { 0 }; + int32_t db { 0 }; + }; + + using RSSIGraphList = std::vector; + + class RSSIGraph : public Widget { + public: + RSSIGraph( + const Rect parent_rect + ) : Widget { parent_rect } + { + } + void paint(Painter& painter) override; + void add_values(int32_t rssi_min, int32_t rssi_avg, int32_t rssi_max, int32_t db ); + + private: + RSSIGraphList graph_list { } ; + }; }