2015-07-08 15:39:24 +00:00
/*
* Copyright ( C ) 2015 Jared Boone , ShareBrained Technology , Inc .
2016-07-30 03:27:28 +00:00
* Copyright ( C ) 2016 Furrtek
2015-07-08 15:39:24 +00:00
*
* 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 .
*/
# include "ui_navigation.hpp"
2016-04-28 12:59:14 +00:00
2023-05-23 04:39:22 +00:00
// #include "modules.h"
2015-07-08 15:39:24 +00:00
2015-10-17 02:39:44 +00:00
# include "portapack.hpp"
2016-01-31 08:34:24 +00:00
# include "event_m0.hpp"
2016-08-23 06:45:33 +00:00
# include "bmp_splash.hpp"
# include "bmp_modal_warning.hpp"
2017-06-11 01:53:06 +00:00
# include "portapack_persistent_memory.hpp"
2023-04-23 19:48:45 +00:00
# include "portapack_shared_memory.hpp"
2015-07-08 15:39:24 +00:00
2020-08-08 21:06:53 +00:00
# include "ui_about_simple.hpp"
2017-07-14 09:02:21 +00:00
# include "ui_adsb_rx.hpp"
2017-10-14 15:30:49 +00:00
# include "ui_adsb_tx.hpp"
2017-08-29 08:42:04 +00:00
# include "ui_afsk_rx.hpp"
2021-03-07 22:05:23 +00:00
# include "ui_aprs_rx.hpp"
2020-04-20 04:50:03 +00:00
# include "ui_btle_rx.hpp"
2020-04-20 04:45:28 +00:00
# include "ui_nrf_rx.hpp"
2017-10-14 15:30:49 +00:00
# include "ui_aprs_tx.hpp"
2017-01-16 08:40:17 +00:00
# include "ui_bht_tx.hpp"
2017-04-07 05:20:24 +00:00
# include "ui_coasterp.hpp"
2020-04-21 12:22:09 +00:00
# include "ui_debug.hpp"
2016-12-09 17:21:47 +00:00
# include "ui_encoders.hpp"
2017-09-19 19:14:56 +00:00
# include "ui_fileman.hpp"
2023-06-07 15:33:32 +00:00
# include "ui_font_fixed_8x16.hpp"
2016-12-05 11:56:41 +00:00
# include "ui_freqman.hpp"
2016-12-09 17:21:47 +00:00
# include "ui_jammer.hpp"
2023-05-23 04:39:22 +00:00
// #include "ui_keyfob.hpp"
2016-12-09 17:21:47 +00:00
# include "ui_lcr.hpp"
2017-03-22 03:21:06 +00:00
# include "ui_mictx.hpp"
2016-12-09 17:21:47 +00:00
# include "ui_morse.hpp"
2023-05-23 04:39:22 +00:00
// #include "ui_numbers.hpp"
// #include "ui_nuoptix.hpp"
// #include "ui_playdead.hpp"
2017-02-07 17:48:17 +00:00
# include "ui_pocsag_tx.hpp"
2016-07-27 01:03:40 +00:00
# include "ui_rds.hpp"
2018-03-27 11:52:07 +00:00
# include "ui_remote.hpp"
2017-05-18 10:06:11 +00:00
# include "ui_scanner.hpp"
2018-03-27 11:52:07 +00:00
# include "ui_search.hpp"
2022-09-11 14:10:35 +00:00
# include "ui_recon.hpp"
2023-03-10 13:25:38 +00:00
# include "ui_level.hpp"
2017-10-14 15:30:49 +00:00
# include "ui_sd_wipe.hpp"
2018-05-16 08:45:13 +00:00
# include "ui_settings.hpp"
2017-10-14 15:30:49 +00:00
# include "ui_siggen.hpp"
# include "ui_sonde.hpp"
2017-03-22 18:21:31 +00:00
# include "ui_sstvtx.hpp"
2023-06-07 15:33:32 +00:00
# include "ui_styles.hpp"
2023-05-23 04:39:22 +00:00
// #include "ui_test.hpp"
2023-05-19 20:39:35 +00:00
# include "ui_text_editor.hpp"
2018-02-23 20:21:24 +00:00
# include "ui_tone_search.hpp"
2017-09-23 11:02:32 +00:00
# include "ui_touchtunes.hpp"
2022-04-03 23:38:06 +00:00
# include "ui_playlist.hpp"
2017-10-15 14:53:40 +00:00
# include "ui_view_wav.hpp"
2016-12-09 17:21:47 +00:00
# include "ui_whipcalc.hpp"
2023-03-28 12:39:00 +00:00
# include "ui_flash_utility.hpp"
2023-03-29 15:05:11 +00:00
# include "ui_sd_over_usb.hpp"
2023-05-14 21:09:43 +00:00
# include "ui_spectrum_painter.hpp"
2016-12-09 17:21:47 +00:00
2023-05-23 04:39:22 +00:00
// #include "acars_app.hpp"
2016-01-31 08:34:24 +00:00
# include "ais_app.hpp"
2018-06-10 09:15:43 +00:00
# include "analog_audio_app.hpp"
2020-04-20 04:50:24 +00:00
# include "analog_tv_app.hpp"
2018-06-10 09:15:43 +00:00
# include "capture_app.hpp"
2016-01-31 08:34:24 +00:00
# include "ert_app.hpp"
2019-02-06 17:34:53 +00:00
# include "lge_app.hpp"
2016-08-23 06:45:33 +00:00
# include "pocsag_app.hpp"
2017-01-10 19:45:40 +00:00
# include "replay_app.hpp"
2020-04-17 23:17:13 +00:00
# include "gps_sim_app.hpp"
2018-12-18 16:25:21 +00:00
# include "soundboard_app.hpp"
2018-06-10 09:15:43 +00:00
# include "tpms_app.hpp"
2016-01-31 08:34:24 +00:00
2016-02-16 19:09:00 +00:00
# include "core_control.hpp"
2020-10-21 16:21:34 +00:00
# include "ui_looking_glass_app.hpp"
2016-04-20 17:22:05 +00:00
# include "file.hpp"
2016-02-19 23:34:02 +00:00
# include "png_writer.hpp"
2015-07-08 15:39:24 +00:00
2018-01-07 23:13:08 +00:00
using portapack : : receiver_model ;
2018-02-22 07:04:19 +00:00
using portapack : : transmitter_model ;
2018-01-07 23:13:08 +00:00
2015-07-08 15:39:24 +00:00
namespace ui {
/* SystemStatusView ******************************************************/
2018-01-08 03:47:37 +00:00
SystemStatusView : : SystemStatusView (
2023-05-18 20:16:05 +00:00
NavigationView & nav )
: nav_ ( nav ) {
add_children ( {
& backdrop ,
& button_back ,
& title ,
& button_title ,
& button_converter ,
& button_speaker ,
& button_stealth ,
//&button_textentry,
& button_camera ,
& button_sleep ,
& button_bias_tee ,
& button_clock_status ,
& sd_card_status_view ,
} ) ;
2023-06-04 19:25:25 +00:00
if ( portapack : : persistent_memory : : should_use_sdcard_for_pmem ( ) ) {
portapack : : persistent_memory : : load_persistent_settings_from_file ( ) ;
}
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : config_hide_converter ( ) ) {
button_converter . hidden ( true ) ;
} else {
button_converter . hidden ( false ) ;
if ( portapack : : persistent_memory : : config_converter ( ) ) {
button_converter . set_foreground ( Color : : red ( ) ) ;
} else {
button_converter . set_foreground ( Color : : light_grey ( ) ) ;
}
}
button_back . id = - 1 ; // Special ID used by FocusManager
2023-06-07 15:33:32 +00:00
title . set_style ( & Styles : : bg_dark_grey ) ;
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : stealth_mode ( ) )
button_stealth . set_foreground ( ui : : Color : : green ( ) ) ;
/*if (!portapack::persistent_memory::ui_config_textentry())
button_textentry . set_bitmap ( & bitmap_icon_keyboard ) ;
else
button_textentry . set_bitmap ( & bitmap_icon_unistroke ) ; */
refresh ( ) ;
button_back . on_select = [ this ] ( ImageButton & ) {
2023-06-04 19:25:25 +00:00
if ( portapack : : persistent_memory : : should_use_sdcard_for_pmem ( ) ) {
portapack : : persistent_memory : : save_persistent_settings_to_file ( ) ;
}
2023-05-18 20:16:05 +00:00
if ( this - > on_back )
this - > on_back ( ) ;
} ;
button_title . on_select = [ this ] ( ImageButton & ) {
this - > on_title ( ) ;
} ;
button_converter . on_select = [ this ] ( ImageButton & ) {
this - > on_converter ( ) ;
} ;
button_speaker . on_select = [ this ] ( ImageButton & ) {
this - > on_speaker ( ) ;
} ;
button_stealth . on_select = [ this ] ( ImageButton & ) {
this - > on_stealth ( ) ;
} ;
button_bias_tee . on_select = [ this ] ( ImageButton & ) {
this - > on_bias_tee ( ) ;
} ;
/*button_textentry.on_select = [this](ImageButton&) {
this - > on_textentry ( ) ;
} ; */
button_camera . on_select = [ this ] ( ImageButton & ) {
this - > on_camera ( ) ;
} ;
button_sleep . on_select = [ this ] ( ImageButton & ) {
DisplaySleepMessage message ;
EventDispatcher : : send_message ( message ) ;
} ;
button_clock_status . on_select = [ this ] ( ImageButton & ) {
this - > on_clk ( ) ;
} ;
2023-06-19 19:06:07 +00:00
audio : : output : : update_audio_mute ( ) ;
2016-01-31 08:34:24 +00:00
}
2018-01-07 23:13:08 +00:00
void SystemStatusView : : refresh ( ) {
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : config_hide_converter ( ) ) {
button_converter . hidden ( true ) ;
} else {
if ( portapack : : persistent_memory : : config_updown_converter ( ) ) {
button_converter . set_bitmap ( & bitmap_icon_downconvert ) ;
} else {
button_converter . set_bitmap ( & bitmap_icon_upconvert ) ;
}
button_converter . hidden ( false ) ;
if ( portapack : : persistent_memory : : config_converter ( ) ) {
button_converter . set_foreground ( Color : : red ( ) ) ;
} else {
button_converter . set_foreground ( Color : : light_grey ( ) ) ;
}
}
2023-06-17 21:15:21 +00:00
if ( portapack : : persistent_memory : : config_audio_mute ( ) ) {
2023-05-18 20:16:05 +00:00
button_speaker . set_foreground ( Color : : light_grey ( ) ) ;
button_speaker . set_bitmap ( & bitmap_icon_speaker_mute ) ;
} else {
2023-06-17 21:15:21 +00:00
button_speaker . set_foreground ( Color : : green ( ) ) ;
button_speaker . set_bitmap ( & bitmap_icon_speaker ) ;
2023-05-18 20:16:05 +00:00
}
if ( portapack : : get_antenna_bias ( ) ) {
button_bias_tee . set_bitmap ( & bitmap_icon_biast_on ) ;
button_bias_tee . set_foreground ( ui : : Color : : yellow ( ) ) ;
} else {
button_bias_tee . set_bitmap ( & bitmap_icon_biast_off ) ;
button_bias_tee . set_foreground ( ui : : Color : : light_grey ( ) ) ;
}
if ( portapack : : clock_manager . get_reference ( ) . source = = ClockManager : : ReferenceSource : : External ) {
button_clock_status . set_bitmap ( & bitmap_icon_clk_ext ) ;
} else {
button_clock_status . set_bitmap ( & bitmap_icon_clk_int ) ;
}
if ( portapack : : persistent_memory : : clkout_enabled ( ) ) {
button_clock_status . set_foreground ( ui : : Color : : green ( ) ) ;
} else {
button_clock_status . set_foreground ( ui : : Color : : light_grey ( ) ) ;
}
set_dirty ( ) ;
2018-01-07 23:13:08 +00:00
}
2016-02-07 18:33:15 +00:00
void SystemStatusView : : set_back_enabled ( bool new_value ) {
2023-05-18 20:16:05 +00:00
if ( new_value ) {
add_child ( & button_back ) ;
} else {
remove_child ( & button_back ) ;
}
2020-08-02 01:55:09 +00:00
}
void SystemStatusView : : set_title_image_enabled ( bool new_value ) {
2023-05-18 20:16:05 +00:00
if ( new_value ) {
add_child ( & button_title ) ;
} else {
remove_child ( & button_title ) ;
}
2016-01-31 08:34:24 +00:00
}
void SystemStatusView : : set_title ( const std : : string new_value ) {
2023-05-18 20:16:05 +00:00
if ( new_value . empty ( ) ) {
title . set ( default_title ) ;
} else {
title . set ( new_value ) ;
}
2015-07-08 15:39:24 +00:00
}
2023-03-27 12:22:35 +00:00
void SystemStatusView : : on_converter ( ) {
2023-05-18 20:16:05 +00:00
if ( ! portapack : : persistent_memory : : config_converter ( ) ) {
portapack : : persistent_memory : : set_config_converter ( true ) ;
button_converter . set_foreground ( Color : : red ( ) ) ;
} else {
portapack : : persistent_memory : : set_config_converter ( false ) ;
button_converter . set_foreground ( Color : : light_grey ( ) ) ;
}
2023-06-11 18:47:13 +00:00
2023-06-17 21:15:21 +00:00
// Poke to update tuning
// NOTE: Code assumes here that a TX app isn't active, since RX & TX have diff tuning offsets
// (and there's only one tuner in the radio so can't update tuner for both).
2023-06-11 18:47:13 +00:00
receiver_model . set_target_frequency ( receiver_model . target_frequency ( ) ) ;
2023-05-18 20:16:05 +00:00
}
2023-03-22 07:46:58 +00:00
2020-06-07 23:23:44 +00:00
void SystemStatusView : : on_speaker ( ) {
2023-06-19 19:06:07 +00:00
portapack : : persistent_memory : : set_config_audio_mute ( ! portapack : : persistent_memory : : config_audio_mute ( ) ) ;
audio : : output : : update_audio_mute ( ) ;
2023-06-17 21:15:21 +00:00
refresh ( ) ;
2023-05-18 20:16:05 +00:00
}
2020-06-07 23:23:44 +00:00
2016-12-09 17:21:47 +00:00
void SystemStatusView : : on_stealth ( ) {
2023-05-18 20:16:05 +00:00
bool mode = not portapack : : persistent_memory : : stealth_mode ( ) ;
portapack : : persistent_memory : : set_stealth_mode ( mode ) ;
2018-02-22 07:04:19 +00:00
2023-05-18 20:16:05 +00:00
button_stealth . set_foreground ( mode ? Color : : green ( ) : Color : : light_grey ( ) ) ;
2016-12-09 17:21:47 +00:00
}
2018-01-08 03:47:37 +00:00
void SystemStatusView : : on_bias_tee ( ) {
2023-05-24 04:22:30 +00:00
if ( ! portapack : : get_antenna_bias ( ) ) {
2023-05-18 20:16:05 +00:00
nav_ . display_modal ( " Bias voltage " , " Enable DC voltage on \n antenna connector? " , YESNO , [ this ] ( bool v ) {
if ( v ) {
portapack : : set_antenna_bias ( true ) ;
receiver_model . set_antenna_bias ( ) ;
transmitter_model . set_antenna_bias ( ) ;
refresh ( ) ;
}
} ) ;
} else {
portapack : : set_antenna_bias ( false ) ;
receiver_model . set_antenna_bias ( ) ;
transmitter_model . set_antenna_bias ( ) ;
2023-05-24 04:22:30 +00:00
// Ensure this is disabled. The models don't actually
// update the radio unless they are 'enabled_'.
radio : : set_antenna_bias ( false ) ;
2023-05-18 20:16:05 +00:00
refresh ( ) ;
}
2018-01-08 03:47:37 +00:00
}
2017-09-20 06:50:59 +00:00
/*void SystemStatusView::on_textentry() {
2023-05-18 20:16:05 +00:00
uint8_t cfg ;
cfg = portapack : : persistent_memory : : ui_config_textentry ( ) ;
portapack : : persistent_memory : : set_config_textentry ( cfg ^ 1 ) ;
if ( ! cfg )
button_textentry . set_bitmap ( & bitmap_icon_unistroke ) ;
else
button_textentry . set_bitmap ( & bitmap_icon_keyboard ) ;
2017-09-20 06:50:59 +00:00
} */
2016-05-29 10:06:47 +00:00
2016-02-19 05:35:46 +00:00
void SystemStatusView : : on_camera ( ) {
2023-05-18 20:16:05 +00:00
ensure_directory ( " SCREENSHOTS " ) ;
auto path = next_filename_matching_pattern ( u " SCREENSHOTS/SCR_????.PNG " ) ;
2023-05-12 18:08:07 +00:00
2023-05-18 20:16:05 +00:00
if ( path . empty ( ) ) {
return ;
}
2016-04-20 17:22:05 +00:00
2023-05-18 20:16:05 +00:00
PNGWriter png ;
auto create_error = png . create ( path ) ;
if ( create_error . is_valid ( ) ) {
return ;
}
2016-02-19 23:34:02 +00:00
2023-05-18 20:16:05 +00:00
for ( int i = 0 ; i < 320 ; i + + ) {
std : : array < ColorRGB888 , 240 > row ;
portapack : : display . read_pixels ( { 0 , i , 240 , 1 } , row ) ;
png . write_scanline ( row ) ;
}
2016-02-19 05:35:46 +00:00
}
2020-09-16 11:27:56 +00:00
void SystemStatusView : : on_clk ( ) {
2023-05-18 20:16:05 +00:00
bool v = portapack : : persistent_memory : : clkout_enabled ( ) ;
if ( v ) {
v = false ;
} else {
v = true ;
}
portapack : : clock_manager . enable_clock_output ( v ) ;
portapack : : persistent_memory : : set_clkout_enabled ( v ) ;
refresh ( ) ;
2020-09-16 11:27:56 +00:00
}
2020-08-02 01:55:09 +00:00
void SystemStatusView : : on_title ( ) {
2023-05-18 20:16:05 +00:00
if ( nav_ . is_top ( ) )
nav_ . push < AboutView > ( ) ;
else
nav_ . pop ( ) ;
2020-08-02 01:55:09 +00:00
}
2020-08-05 05:03:51 +00:00
/* Information View *****************************************************/
InformationView : : InformationView (
2023-05-18 20:16:05 +00:00
NavigationView & nav )
: nav_ ( nav ) {
static constexpr Style style_infobar {
. font = font : : fixed_8x16 ,
. background = { 33 , 33 , 33 } ,
. foreground = Color : : white ( ) ,
} ;
add_children ( { & backdrop ,
& version ,
& ltime } ) ;
version . set_style ( & style_infobar ) ;
ltime . set_hide_clock ( portapack : : persistent_memory : : hide_clock ( ) ) ;
ltime . set_style ( & style_infobar ) ;
ltime . set_seconds_enabled ( true ) ;
ltime . set_date_enabled ( portapack : : persistent_memory : : clock_with_date ( ) ) ;
set_dirty ( ) ;
2020-08-02 01:55:09 +00:00
}
2021-05-16 09:41:09 +00:00
void InformationView : : refresh ( ) {
2023-05-18 20:16:05 +00:00
ltime . set_hide_clock ( portapack : : persistent_memory : : hide_clock ( ) ) ;
ltime . set_seconds_enabled ( true ) ;
ltime . set_date_enabled ( portapack : : persistent_memory : : clock_with_date ( ) ) ;
2021-05-16 09:41:09 +00:00
}
2015-07-08 15:39:24 +00:00
/* Navigation ************************************************************/
2016-01-31 08:34:24 +00:00
bool NavigationView : : is_top ( ) const {
2023-05-18 20:16:05 +00:00
return view_stack . size ( ) = = 1 ;
2015-07-08 15:39:24 +00:00
}
2016-01-31 08:34:24 +00:00
View * NavigationView : : push_view ( std : : unique_ptr < View > new_view ) {
2023-05-18 20:16:05 +00:00
free_view ( ) ;
2016-01-31 08:34:24 +00:00
2023-05-18 20:16:05 +00:00
const auto p = new_view . get ( ) ;
2023-06-01 22:45:55 +00:00
view_stack . emplace_back ( ViewState { std : : move ( new_view ) , { } } ) ;
2016-01-31 08:34:24 +00:00
2023-05-18 20:16:05 +00:00
update_view ( ) ;
2016-01-31 08:34:24 +00:00
2023-05-18 20:16:05 +00:00
return p ;
2015-07-08 15:39:24 +00:00
}
void NavigationView : : pop ( ) {
2023-06-01 22:45:55 +00:00
pop ( true ) ;
2015-07-08 15:39:24 +00:00
}
2016-12-06 12:31:38 +00:00
void NavigationView : : pop_modal ( ) {
2023-06-01 22:45:55 +00:00
// Pop modal view + underlying app view.
// TODO: this shouldn't be necessary.
pop ( false ) ;
pop ( true ) ;
2016-12-06 12:31:38 +00:00
}
2016-05-17 17:15:34 +00:00
void NavigationView : : display_modal (
2023-05-18 20:16:05 +00:00
const std : : string & title ,
const std : : string & message ) {
display_modal ( title , message , INFO , nullptr ) ;
2016-12-06 12:31:38 +00:00
}
void NavigationView : : display_modal (
2023-05-18 20:16:05 +00:00
const std : : string & title ,
const std : : string & message ,
const modal_t type ,
const std : : function < void ( bool ) > on_choice ) {
/* If a modal view is already visible, don't display another */
if ( ! modal_view ) {
modal_view = push < ModalMessageView > ( title , message , type , on_choice ) ;
}
2016-05-17 16:33:16 +00:00
}
2023-06-01 22:45:55 +00:00
void NavigationView : : pop ( bool update ) {
if ( view ( ) = = modal_view ) {
modal_view = nullptr ;
}
// Can't pop last item from stack.
if ( view_stack . size ( ) > 1 ) {
auto on_pop = view_stack . back ( ) . on_pop ;
free_view ( ) ;
view_stack . pop_back ( ) ;
if ( update )
update_view ( ) ;
if ( on_pop ) on_pop ( ) ;
}
}
2016-01-31 08:34:24 +00:00
void NavigationView : : free_view ( ) {
2023-05-18 20:16:05 +00:00
remove_child ( view ( ) ) ;
2015-07-08 15:39:24 +00:00
}
2016-01-31 08:34:24 +00:00
void NavigationView : : update_view ( ) {
2023-06-01 22:45:55 +00:00
const auto new_view = view_stack . back ( ) . view . get ( ) ;
2023-05-18 20:16:05 +00:00
add_child ( new_view ) ;
new_view - > set_parent_rect ( { { 0 , 0 } , size ( ) } ) ;
2015-07-08 15:39:24 +00:00
2023-05-18 20:16:05 +00:00
focus ( ) ;
set_dirty ( ) ;
if ( on_view_changed ) {
on_view_changed ( * new_view ) ;
}
2016-01-31 08:34:24 +00:00
}
2015-07-08 15:39:24 +00:00
2016-01-31 08:34:24 +00:00
Widget * NavigationView : : view ( ) const {
2023-05-18 20:16:05 +00:00
return children_ . empty ( ) ? nullptr : children_ [ 0 ] ;
2015-07-08 15:39:24 +00:00
}
void NavigationView : : focus ( ) {
2023-05-18 20:16:05 +00:00
if ( view ( ) ) {
view ( ) - > focus ( ) ;
}
2015-07-08 15:39:24 +00:00
}
2023-06-01 22:45:55 +00:00
bool NavigationView : : set_on_pop ( std : : function < void ( ) > on_pop ) {
if ( view_stack . size ( ) < = 1 )
return false ;
auto & top = view_stack . back ( ) ;
if ( top . on_pop )
return false ;
top . on_pop = on_pop ;
return true ;
}
2017-05-25 20:36:30 +00:00
/* ReceiversMenuView *****************************************************/
2016-01-31 08:34:24 +00:00
2017-05-25 20:36:30 +00:00
ReceiversMenuView : : ReceiversMenuView ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : show_gui_return_icon ( ) ) {
add_items ( { { " .. " , ui : : Color : : light_grey ( ) , & bitmap_icon_previous , [ & nav ] ( ) { nav . pop ( ) ; } } } ) ;
}
add_items ( {
{
" ADS-B " ,
ui : : Color : : green ( ) ,
& bitmap_icon_adsb ,
[ & nav ] ( ) { nav . push < ADSBRxView > ( ) ; } ,
} ,
//{ "ACARS", ui::Color::yellow(), &bitmap_icon_adsb, [&nav](){ nav.push<ACARSAppView>(); }, },
{ " AIS Boats " , ui : : Color : : green ( ) , & bitmap_icon_ais , [ & nav ] ( ) { nav . push < AISAppView > ( ) ; } } ,
{ " AFSK " , ui : : Color : : yellow ( ) , & bitmap_icon_modem , [ & nav ] ( ) { nav . push < AFSKRxView > ( ) ; } } ,
{ " BTLE " , ui : : Color : : yellow ( ) , & bitmap_icon_btle , [ & nav ] ( ) { nav . push < BTLERxView > ( ) ; } } ,
{ " NRF " , ui : : Color : : yellow ( ) , & bitmap_icon_nrf , [ & nav ] ( ) { nav . push < NRFRxView > ( ) ; } } ,
{ " Audio " , ui : : Color : : green ( ) , & bitmap_icon_speaker , [ & nav ] ( ) { nav . push < AnalogAudioView > ( ) ; } } ,
{ " Analog TV " , ui : : Color : : yellow ( ) , & bitmap_icon_sstv , [ & nav ] ( ) { nav . push < AnalogTvView > ( ) ; } } ,
{ " ERT Meter " , ui : : Color : : green ( ) , & bitmap_icon_ert , [ & nav ] ( ) { nav . push < ERTAppView > ( ) ; } } ,
{ " POCSAG " , ui : : Color : : green ( ) , & bitmap_icon_pocsag , [ & nav ] ( ) { nav . push < POCSAGAppView > ( ) ; } } ,
{ " Radiosnde " , ui : : Color : : green ( ) , & bitmap_icon_sonde , [ & nav ] ( ) { nav . push < SondeView > ( ) ; } } ,
{ " TPMS Cars " , ui : : Color : : green ( ) , & bitmap_icon_tpms , [ & nav ] ( ) { nav . push < TPMSAppView > ( ) ; } } ,
{ " Recon " , ui : : Color : : green ( ) , & bitmap_icon_scanner , [ & nav ] ( ) { nav . push < ReconView > ( ) ; } } ,
{ " Level " , ui : : Color : : green ( ) , & bitmap_icon_options_radio , [ & nav ] ( ) { nav . push < LevelView > ( ) ; } } ,
{ " APRS " , ui : : Color : : green ( ) , & bitmap_icon_aprs , [ & nav ] ( ) { nav . push < APRSRXView > ( ) ; } }
/*
{ " DMR " , ui : : Color : : dark_grey ( ) , & bitmap_icon_dmr , [ & nav ] ( ) { nav . push < NotImplementedView > ( ) ; } } ,
{ " SIGFOX " , ui : : Color : : dark_grey ( ) , & bitmap_icon_fox , [ & nav ] ( ) { nav . push < NotImplementedView > ( ) ; } } , // SIGFRXView
{ " LoRa " , ui : : Color : : dark_grey ( ) , & bitmap_icon_lora , [ & nav ] ( ) { nav . push < NotImplementedView > ( ) ; } } ,
{ " SSTV " , ui : : Color : : dark_grey ( ) , & bitmap_icon_sstv , [ & nav ] ( ) { nav . push < NotImplementedView > ( ) ; } } ,
{ " TETRA " , ui : : Color : : dark_grey ( ) , & bitmap_icon_tetra , [ & nav ] ( ) { nav . push < NotImplementedView > ( ) ; } } , */
} ) ;
// set_highlighted(0); // Default selection is "Audio"
2016-11-30 06:41:55 +00:00
}
2017-05-25 20:36:30 +00:00
/* TransmittersMenuView **************************************************/
TransmittersMenuView : : TransmittersMenuView ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : show_gui_return_icon ( ) ) {
add_items ( { { " .. " , ui : : Color : : light_grey ( ) , & bitmap_icon_previous , [ & nav ] ( ) { nav . pop ( ) ; } } } ) ;
}
add_items ( {
{ " ADS-B [S] " , ui : : Color : : yellow ( ) , & bitmap_icon_adsb , [ & nav ] ( ) { nav . push < ADSBTxView > ( ) ; } } ,
{ " APRS " , ui : : Color : : green ( ) , & bitmap_icon_aprs , [ & nav ] ( ) { nav . push < APRSTXView > ( ) ; } } ,
{ " BHT Xy/EP " , ui : : Color : : green ( ) , & bitmap_icon_bht , [ & nav ] ( ) { nav . push < BHTView > ( ) ; } } ,
{ " GPS Sim " , ui : : Color : : yellow ( ) , & bitmap_icon_gps_sim , [ & nav ] ( ) { nav . push < GpsSimAppView > ( ) ; } } ,
{ " Jammer " , ui : : Color : : green ( ) , & bitmap_icon_jammer , [ & nav ] ( ) { nav . push < JammerView > ( ) ; } } ,
//{ "Key fob", ui::Color::orange(), &bitmap_icon_keyfob, [&nav](){ nav.push<KeyfobView>(); } },
{ " LGE tool " , ui : : Color : : yellow ( ) , & bitmap_icon_lge , [ & nav ] ( ) { nav . push < LGEView > ( ) ; } } ,
{ " Morse " , ui : : Color : : green ( ) , & bitmap_icon_morse , [ & nav ] ( ) { nav . push < MorseView > ( ) ; } } ,
{ " BurgerPgr " , ui : : Color : : yellow ( ) , & bitmap_icon_burger , [ & nav ] ( ) { nav . push < CoasterPagerView > ( ) ; } } ,
//{ "Nuoptix DTMF", ui::Color::green(), &bitmap_icon_nuoptix, [&nav](){ nav.push<NuoptixView>(); } },
{ " OOK " , ui : : Color : : yellow ( ) , & bitmap_icon_remote , [ & nav ] ( ) { nav . push < EncodersView > ( ) ; } } ,
{ " POCSAG " , ui : : Color : : green ( ) , & bitmap_icon_pocsag , [ & nav ] ( ) { nav . push < POCSAGTXView > ( ) ; } } ,
{ " RDS " , ui : : Color : : green ( ) , & bitmap_icon_rds , [ & nav ] ( ) { nav . push < RDSView > ( ) ; } } ,
{ " Soundbrd " , ui : : Color : : green ( ) , & bitmap_icon_soundboard , [ & nav ] ( ) { nav . push < SoundBoardView > ( ) ; } } ,
{ " SSTV " , ui : : Color : : green ( ) , & bitmap_icon_sstv , [ & nav ] ( ) { nav . push < SSTVTXView > ( ) ; } } ,
{ " TEDI/LCR " , ui : : Color : : yellow ( ) , & bitmap_icon_lcr , [ & nav ] ( ) { nav . push < LCRView > ( ) ; } } ,
{ " TouchTune " , ui : : Color : : yellow ( ) , & bitmap_icon_remote , [ & nav ] ( ) { nav . push < TouchTunesView > ( ) ; } } ,
2023-05-23 04:39:22 +00:00
{ " Playlist " , ui : : Color : : green ( ) , & bitmap_icon_scanner , [ & nav ] ( ) { nav . push < PlaylistView > ( ) ; } } ,
2023-05-18 20:16:05 +00:00
{ " S.Painter " , ui : : Color : : orange ( ) , & bitmap_icon_morse , [ & nav ] ( ) { nav . push < SpectrumPainterView > ( ) ; } } ,
//{ "Remote", ui::Color::dark_grey(), &bitmap_icon_remote, [&nav](){ nav.push<RemoteView>(); } },
} ) ;
2016-01-31 08:34:24 +00:00
}
2017-05-25 20:36:30 +00:00
/* UtilitiesMenuView *****************************************************/
2016-12-06 12:31:38 +00:00
2017-05-25 20:36:30 +00:00
UtilitiesMenuView : : UtilitiesMenuView ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
if ( portapack : : persistent_memory : : show_gui_return_icon ( ) ) {
add_items ( { { " .. " , ui : : Color : : light_grey ( ) , & bitmap_icon_previous , [ & nav ] ( ) { nav . pop ( ) ; } } } ) ;
}
add_items ( {
//{ "Test app", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<TestView>(); } },
{ " Freq. manager " , ui : : Color : : green ( ) , & bitmap_icon_freqman , [ & nav ] ( ) { nav . push < FrequencyManagerView > ( ) ; } } ,
{ " File manager " , ui : : Color : : yellow ( ) , & bitmap_icon_dir , [ & nav ] ( ) { nav . push < FileManagerView > ( ) ; } } ,
2023-05-19 20:39:35 +00:00
{ " Notepad " , ui : : Color : : dark_cyan ( ) , & bitmap_icon_notepad , [ & nav ] ( ) { nav . push < TextEditorView > ( ) ; } } ,
2023-05-18 20:16:05 +00:00
{ " Signal gen " , ui : : Color : : green ( ) , & bitmap_icon_cwgen , [ & nav ] ( ) { nav . push < SigGenView > ( ) ; } } ,
//{ "Tone search", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<ToneSearchView>(); } },
{ " Wav viewer " , ui : : Color : : yellow ( ) , & bitmap_icon_soundboard , [ & nav ] ( ) { nav . push < ViewWavView > ( ) ; } } ,
{ " Antenna length " , ui : : Color : : green ( ) , & bitmap_icon_tools_antenna , [ & nav ] ( ) { nav . push < WhipCalcView > ( ) ; } } ,
{ " Wipe SD card " , ui : : Color : : red ( ) , & bitmap_icon_tools_wipesd , [ & nav ] ( ) { nav . push < WipeSDView > ( ) ; } } ,
{ " Flash Utility " , ui : : Color : : red ( ) , & bitmap_icon_temperature , [ & nav ] ( ) { nav . push < FlashUtilityView > ( ) ; } } ,
{ " SD over USB " , ui : : Color : : yellow ( ) , & bitmap_icon_hackrf , [ & nav ] ( ) { nav . push < SdOverUsbView > ( ) ; } } ,
} ) ;
set_max_rows ( 2 ) ; // allow wider buttons
2016-12-06 12:31:38 +00:00
}
2017-05-25 20:36:30 +00:00
2015-07-08 15:39:24 +00:00
/* SystemMenuView ********************************************************/
2016-12-26 00:31:38 +00:00
void SystemMenuView : : hackrf_mode ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
nav . push < ModalMessageView > ( " HackRF mode " , " This mode enables HackRF \n functionality. To return, \n press the reset button. \n \n Switch to HackRF mode? " , YESNO ,
[ this ] ( bool choice ) {
if ( choice ) {
EventDispatcher : : request_stop ( ) ;
}
} ) ;
2016-12-26 00:31:38 +00:00
}
2015-07-08 15:39:24 +00:00
SystemMenuView : : SystemMenuView ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
add_items ( {
//{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
{ " Receive " , ui : : Color : : cyan ( ) , & bitmap_icon_receivers , [ & nav ] ( ) { nav . push < ReceiversMenuView > ( ) ; } } ,
{ " Transmit " , ui : : Color : : cyan ( ) , & bitmap_icon_transmit , [ & nav ] ( ) { nav . push < TransmittersMenuView > ( ) ; } } ,
{ " Capture " , ui : : Color : : red ( ) , & bitmap_icon_capture , [ & nav ] ( ) { nav . push < CaptureAppView > ( ) ; } } ,
{ " Replay " , ui : : Color : : green ( ) , & bitmap_icon_replay , [ & nav ] ( ) { nav . push < ReplayAppView > ( ) ; } } ,
{ " Search " , ui : : Color : : yellow ( ) , & bitmap_icon_search , [ & nav ] ( ) { nav . push < SearchView > ( ) ; } } ,
{ " Scanner " , ui : : Color : : yellow ( ) , & bitmap_icon_scanner , [ & nav ] ( ) { nav . push < ScannerView > ( ) ; } } ,
{ " Microphone " , ui : : Color : : yellow ( ) , & bitmap_icon_microphone , [ & nav ] ( ) { nav . push < MicTXView > ( ) ; } } ,
{ " Looking Glass " , ui : : Color : : yellow ( ) , & bitmap_icon_looking , [ & nav ] ( ) { nav . push < GlassView > ( ) ; } } ,
{ " Utilities " , ui : : Color : : cyan ( ) , & bitmap_icon_utilities , [ & nav ] ( ) { nav . push < UtilitiesMenuView > ( ) ; } } ,
{ " Settings " , ui : : Color : : cyan ( ) , & bitmap_icon_setup , [ & nav ] ( ) { nav . push < SettingsMenuView > ( ) ; } } ,
{ " Debug " , ui : : Color : : light_grey ( ) , & bitmap_icon_debug , [ & nav ] ( ) { nav . push < DebugMenuView > ( ) ; } } ,
{ " HackRF " , ui : : Color : : cyan ( ) , & bitmap_icon_hackrf , [ this , & nav ] ( ) { hackrf_mode ( nav ) ; } } ,
//{ "About", ui::Color::cyan(), nullptr, [&nav](){ nav.push<AboutView>(); } }
} ) ;
set_max_rows ( 2 ) ; // allow wider buttons
set_arrow_enabled ( false ) ;
// set_highlighted(1); // Startup selection
2015-07-08 15:39:24 +00:00
}
/* SystemView ************************************************************/
SystemView : : SystemView (
2023-05-18 20:16:05 +00:00
Context & context ,
const Rect parent_rect )
: View { parent_rect } ,
context_ ( context ) {
2023-06-07 15:33:32 +00:00
set_style ( & ui : : Styles : : white ) ;
2023-05-18 20:16:05 +00:00
constexpr ui : : Dim status_view_height = 16 ;
constexpr ui : : Dim info_view_height = 16 ;
add_child ( & status_view ) ;
status_view . set_parent_rect ( { { 0 , 0 } ,
{ parent_rect . width ( ) , status_view_height } } ) ;
status_view . on_back = [ this ] ( ) {
this - > navigation_view . pop ( ) ;
} ;
add_child ( & navigation_view ) ;
navigation_view . set_parent_rect ( { { 0 , status_view_height } ,
{ parent_rect . width ( ) , static_cast < ui : : Dim > ( parent_rect . height ( ) - status_view_height ) } } ) ;
add_child ( & info_view ) ;
info_view . set_parent_rect ( { { 0 , 19 * 16 } ,
{ parent_rect . width ( ) , info_view_height } } ) ;
navigation_view . on_view_changed = [ this ] ( const View & new_view ) {
if ( ! this - > navigation_view . is_top ( ) ) {
remove_child ( & info_view ) ;
} else {
add_child ( & info_view ) ;
info_view . refresh ( ) ;
}
this - > status_view . set_back_enabled ( ! this - > navigation_view . is_top ( ) ) ;
this - > status_view . set_title_image_enabled ( this - > navigation_view . is_top ( ) ) ;
this - > status_view . set_title ( new_view . title ( ) ) ;
this - > status_view . set_dirty ( ) ;
} ;
// portapack::persistent_memory::set_playdead_sequence(0x8D1);
// Initial view
/*if ((portapack::persistent_memory::playing_dead() == 0x5920C1DF) || // Enable code
( portapack : : persistent_memory : : ui_config ( ) & 16 ) ) { // Login option
navigation_view . push < PlayDeadView > ( ) ;
} else { */
navigation_view . push < SystemMenuView > ( ) ;
if ( portapack : : persistent_memory : : config_splash ( ) ) {
navigation_view . push < BMPView > ( ) ;
}
status_view . set_back_enabled ( false ) ;
status_view . set_title_image_enabled ( true ) ;
status_view . set_dirty ( ) ;
// else
// navigation_view.push<SystemMenuView>();
//}
2015-07-08 15:39:24 +00:00
}
Context & SystemView : : context ( ) const {
2023-05-18 20:16:05 +00:00
return context_ ;
2015-07-08 15:39:24 +00:00
}
2023-04-23 14:21:33 +00:00
void SystemView : : toggle_overlay ( ) {
2023-05-18 20:16:05 +00:00
if ( overlay_active ) {
this - > remove_child ( & this - > overlay ) ;
this - > set_dirty ( ) ;
shared_memory . request_m4_performance_counter = 0 ;
} else {
this - > add_child ( & this - > overlay ) ;
this - > set_dirty ( ) ;
shared_memory . request_m4_performance_counter = 1 ;
shared_memory . m4_cpu_usage = 0 ;
shared_memory . m4_heap_usage = 0 ;
shared_memory . m4_stack_usage = 0 ;
}
overlay_active = ! overlay_active ;
2023-04-23 14:21:33 +00:00
}
void SystemView : : paint_overlay ( ) {
2023-05-18 20:16:05 +00:00
static bool last_paint_state = false ;
if ( overlay_active ) {
// paint background only every other second
if ( ( ( ( chTimeNow ( ) > > 10 ) & 0x01 ) = = 0x01 ) = = last_paint_state )
return ;
2023-04-23 17:52:38 +00:00
2023-05-18 20:16:05 +00:00
last_paint_state = ! last_paint_state ;
this - > overlay . set_dirty ( ) ;
}
2023-04-23 14:21:33 +00:00
}
2016-02-05 16:40:14 +00:00
/* ***********************************************************************/
void BMPView : : focus ( ) {
2023-05-18 20:16:05 +00:00
button_done . focus ( ) ;
2016-02-05 16:40:14 +00:00
}
BMPView : : BMPView ( NavigationView & nav ) {
2023-05-18 20:16:05 +00:00
add_children ( { & button_done } ) ;
button_done . on_select = [ this , & nav ] ( Button & ) {
nav . pop ( ) ;
} ;
2016-02-05 16:40:14 +00:00
}
2016-12-09 17:21:47 +00:00
void BMPView : : paint ( Painter & ) {
2023-05-18 20:16:05 +00:00
if ( ! portapack : : display . drawBMP2 ( { 0 , 0 } , " splash.bmp " ) )
portapack : : display . drawBMP ( { ( 240 - 230 ) / 2 , ( 320 - 50 ) / 2 - 10 } , splash_bmp , false ) ;
2016-02-05 16:40:14 +00:00
}
2015-07-08 15:39:24 +00:00
/* NotImplementedView ****************************************************/
2020-05-11 09:07:45 +00:00
/*NotImplementedView::NotImplementedView(NavigationView& nav) {
2023-05-18 20:16:05 +00:00
button_done . on_select = [ & nav ] ( Button & ) {
nav . pop ( ) ;
} ;
2015-07-08 15:39:24 +00:00
2023-05-18 20:16:05 +00:00
add_children ( {
& text_title ,
& button_done ,
} ) ;
2015-07-08 15:39:24 +00:00
}
void NotImplementedView : : focus ( ) {
2023-05-18 20:16:05 +00:00
button_done . focus ( ) ;
2020-05-11 09:07:45 +00:00
} */
2015-07-08 15:39:24 +00:00
2016-05-13 04:58:54 +00:00
/* ModalMessageView ******************************************************/
2016-12-09 17:21:47 +00:00
2016-05-17 17:15:34 +00:00
ModalMessageView : : ModalMessageView (
2023-05-18 20:16:05 +00:00
NavigationView & nav ,
const std : : string & title ,
const std : : string & message ,
const modal_t type ,
const std : : function < void ( bool ) > on_choice )
: title_ { title } ,
message_ { message } ,
type_ { type } ,
on_choice_ { on_choice } {
if ( type = = INFO ) {
add_child ( & button_ok ) ;
2023-05-19 20:39:35 +00:00
button_ok . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ )
on_choice_ ( true ) ; // Assumes handler will pop.
else
nav . pop ( ) ;
2023-05-18 20:16:05 +00:00
} ;
} else if ( type = = YESNO ) {
add_children ( { & button_yes ,
& button_no } ) ;
button_yes . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ ) on_choice_ ( true ) ;
nav . pop ( ) ;
} ;
button_no . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ ) on_choice_ ( false ) ;
nav . pop ( ) ;
} ;
} else if ( type = = YESCANCEL ) {
add_children ( { & button_yes ,
& button_no } ) ;
button_yes . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ ) on_choice_ ( true ) ;
nav . pop ( ) ;
} ;
button_no . on_select = [ this , & nav ] ( Button & ) {
// if (on_choice_) on_choice_(false);
nav . pop_modal ( ) ;
} ;
} else { // ABORT
add_child ( & button_ok ) ;
button_ok . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ ) on_choice_ ( true ) ;
nav . pop_modal ( ) ;
} ;
}
2016-05-13 04:58:54 +00:00
}
2017-02-07 19:54:18 +00:00
void ModalMessageView : : paint ( Painter & painter ) {
2023-05-18 20:16:05 +00:00
size_t pos , i = 0 , start = 0 ;
portapack : : display . drawBMP ( { 100 , 48 } , modal_warning_bmp , false ) ;
// Terrible...
while ( ( pos = message_ . find ( " \n " , start ) ) ! = std : : string : : npos ) {
painter . draw_string (
{ 1 * 8 , ( Coord ) ( 120 + ( i * 16 ) ) } ,
style ( ) ,
message_ . substr ( start , pos - start ) ) ;
i + + ;
start = pos + 1 ;
}
painter . draw_string (
{ 1 * 8 , ( Coord ) ( 120 + ( i * 16 ) ) } ,
style ( ) ,
message_ . substr ( start , pos ) ) ;
2016-08-23 06:45:33 +00:00
}
2016-05-13 04:58:54 +00:00
void ModalMessageView : : focus ( ) {
2023-05-18 20:16:05 +00:00
if ( ( type_ = = YESNO ) | | ( type_ = = YESCANCEL ) ) {
button_yes . focus ( ) ;
} else {
button_ok . focus ( ) ;
}
2016-05-13 04:58:54 +00:00
}
2015-07-08 15:39:24 +00:00
} /* namespace ui */