2015-07-08 11:39:24 -04:00
/*
* Copyright ( C ) 2015 Jared Boone , ShareBrained Technology , Inc .
2016-07-29 23:27:28 -04:00
* Copyright ( C ) 2016 Furrtek
2015-07-08 11:39:24 -04: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 08:59:14 -04:00
2023-05-23 00:39:22 -04:00
// #include "modules.h"
2015-07-08 11:39:24 -04:00
2015-10-16 22:39:44 -04:00
# include "portapack.hpp"
2016-01-31 03:34:24 -05:00
# include "event_m0.hpp"
2016-08-23 02:45:33 -04:00
# include "bmp_splash.hpp"
# include "bmp_modal_warning.hpp"
2017-06-10 21:53:06 -04:00
# include "portapack_persistent_memory.hpp"
2023-04-23 15:48:45 -04:00
# include "portapack_shared_memory.hpp"
2015-07-08 11:39:24 -04:00
2020-08-08 17:06:53 -04:00
# include "ui_about_simple.hpp"
2017-07-14 05:02:21 -04:00
# include "ui_adsb_rx.hpp"
2017-10-14 11:30:49 -04:00
# include "ui_adsb_tx.hpp"
2017-08-29 04:42:04 -04:00
# include "ui_afsk_rx.hpp"
2021-03-07 17:05:23 -05:00
# include "ui_aprs_rx.hpp"
2020-04-20 00:50:03 -04:00
# include "ui_btle_rx.hpp"
2020-04-20 00:45:28 -04:00
# include "ui_nrf_rx.hpp"
2017-10-14 11:30:49 -04:00
# include "ui_aprs_tx.hpp"
2017-01-16 03:40:17 -05:00
# include "ui_bht_tx.hpp"
2017-04-07 01:20:24 -04:00
# include "ui_coasterp.hpp"
2020-04-21 08:22:09 -04:00
# include "ui_debug.hpp"
2016-12-09 12:21:47 -05:00
# include "ui_encoders.hpp"
2017-09-19 15:14:56 -04:00
# include "ui_fileman.hpp"
2016-12-05 06:56:41 -05:00
# include "ui_freqman.hpp"
2016-12-09 12:21:47 -05:00
# include "ui_jammer.hpp"
2023-05-23 00:39:22 -04:00
// #include "ui_keyfob.hpp"
2016-12-09 12:21:47 -05:00
# include "ui_lcr.hpp"
2017-03-21 23:21:06 -04:00
# include "ui_mictx.hpp"
2016-12-09 12:21:47 -05:00
# include "ui_morse.hpp"
2023-05-23 00:39:22 -04:00
// #include "ui_numbers.hpp"
// #include "ui_nuoptix.hpp"
// #include "ui_playdead.hpp"
2017-02-07 12:48:17 -05:00
# include "ui_pocsag_tx.hpp"
2016-07-26 21:03:40 -04:00
# include "ui_rds.hpp"
2018-03-27 07:52:07 -04:00
# include "ui_remote.hpp"
2017-05-18 06:06:11 -04:00
# include "ui_scanner.hpp"
2018-03-27 07:52:07 -04:00
# include "ui_search.hpp"
2022-09-11 10:10:35 -04:00
# include "ui_recon.hpp"
2023-03-10 08:25:38 -05:00
# include "ui_level.hpp"
2017-10-14 11:30:49 -04:00
# include "ui_sd_wipe.hpp"
2018-05-16 04:45:13 -04:00
# include "ui_settings.hpp"
2017-10-14 11:30:49 -04:00
# include "ui_siggen.hpp"
# include "ui_sonde.hpp"
2017-03-22 14:21:31 -04:00
# include "ui_sstvtx.hpp"
2023-05-23 00:39:22 -04:00
// #include "ui_test.hpp"
2023-05-19 16:39:35 -04:00
# include "ui_text_editor.hpp"
2018-02-23 15:21:24 -05:00
# include "ui_tone_search.hpp"
2017-09-23 07:02:32 -04:00
# include "ui_touchtunes.hpp"
2022-04-03 19:38:06 -04:00
# include "ui_playlist.hpp"
2017-10-15 10:53:40 -04:00
# include "ui_view_wav.hpp"
2016-12-09 12:21:47 -05:00
# include "ui_whipcalc.hpp"
2023-03-28 08:39:00 -04:00
# include "ui_flash_utility.hpp"
2023-03-29 11:05:11 -04:00
# include "ui_sd_over_usb.hpp"
2023-05-14 17:09:43 -04:00
# include "ui_spectrum_painter.hpp"
2016-12-09 12:21:47 -05:00
2023-05-23 00:39:22 -04:00
// #include "acars_app.hpp"
2016-01-31 03:34:24 -05:00
# include "ais_app.hpp"
2018-06-10 05:15:43 -04:00
# include "analog_audio_app.hpp"
2020-04-20 00:50:24 -04:00
# include "analog_tv_app.hpp"
2018-06-10 05:15:43 -04:00
# include "capture_app.hpp"
2016-01-31 03:34:24 -05:00
# include "ert_app.hpp"
2019-02-06 12:34:53 -05:00
# include "lge_app.hpp"
2016-08-23 02:45:33 -04:00
# include "pocsag_app.hpp"
2017-01-10 14:45:40 -05:00
# include "replay_app.hpp"
2020-04-17 19:17:13 -04:00
# include "gps_sim_app.hpp"
2018-12-18 11:25:21 -05:00
# include "soundboard_app.hpp"
2018-06-10 05:15:43 -04:00
# include "tpms_app.hpp"
2016-01-31 03:34:24 -05:00
2016-02-16 14:09:00 -05:00
# include "core_control.hpp"
2020-10-21 12:21:34 -04:00
# include "ui_looking_glass_app.hpp"
2016-04-20 13:22:05 -04:00
# include "file.hpp"
2016-02-19 18:34:02 -05:00
# include "png_writer.hpp"
2015-07-08 11:39:24 -04:00
2018-01-07 18:13:08 -05:00
using portapack : : receiver_model ;
2018-02-22 02:04:19 -05:00
using portapack : : transmitter_model ;
2018-01-07 18:13:08 -05:00
2015-07-08 11:39:24 -04:00
namespace ui {
/* SystemStatusView ******************************************************/
2018-01-07 22:47:37 -05:00
SystemStatusView : : SystemStatusView (
2023-05-18 16:16:05 -04:00
NavigationView & nav )
: nav_ ( nav ) {
static constexpr Style style_systemstatus {
. font = font : : fixed_8x16 ,
. background = Color : : dark_grey ( ) ,
. foreground = Color : : white ( ) ,
} ;
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 ,
} ) ;
if ( portapack : : persistent_memory : : config_speaker ( ) )
button_speaker . hidden ( false ) ;
else
button_speaker . hidden ( true ) ;
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
title . set_style ( & style_systemstatus ) ;
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 & ) {
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 ( ) ;
} ;
2016-01-31 03:34:24 -05:00
}
2018-01-07 18:13:08 -05:00
void SystemStatusView : : refresh ( ) {
2023-05-18 16:16:05 -04: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 ( ) ) ;
}
}
// Retune to take converter change in account
receiver_model . set_tuning_frequency ( portapack : : persistent_memory : : tuned_frequency ( ) ) ;
transmitter_model . set_tuning_frequency ( portapack : : persistent_memory : : tuned_frequency ( ) ) ;
if ( ! portapack : : persistent_memory : : config_speaker ( ) ) {
button_speaker . set_foreground ( Color : : light_grey ( ) ) ;
button_speaker . set_bitmap ( & bitmap_icon_speaker_mute ) ;
button_speaker . hidden ( false ) ;
} else {
button_speaker . hidden ( true ) ;
}
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 ) ;
// button_bias_tee.set_foreground(ui::Color::green()); Typo?
} else {
button_clock_status . set_bitmap ( & bitmap_icon_clk_int ) ;
// button_bias_tee.set_foreground(ui::Color::green());
}
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 18:13:08 -05:00
}
2016-02-07 13:33:15 -05:00
void SystemStatusView : : set_back_enabled ( bool new_value ) {
2023-05-18 16:16:05 -04:00
if ( new_value ) {
add_child ( & button_back ) ;
} else {
remove_child ( & button_back ) ;
}
2020-08-01 21:55:09 -04:00
}
void SystemStatusView : : set_title_image_enabled ( bool new_value ) {
2023-05-18 16:16:05 -04:00
if ( new_value ) {
add_child ( & button_title ) ;
} else {
remove_child ( & button_title ) ;
}
2016-01-31 03:34:24 -05:00
}
void SystemStatusView : : set_title ( const std : : string new_value ) {
2023-05-18 16:16:05 -04:00
if ( new_value . empty ( ) ) {
title . set ( default_title ) ;
} else {
title . set ( new_value ) ;
}
2015-07-08 11:39:24 -04:00
}
2023-03-27 08:22:35 -04:00
void SystemStatusView : : on_converter ( ) {
2023-05-18 16:16:05 -04: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 ( ) ) ;
}
receiver_model . set_tuning_frequency ( portapack : : persistent_memory : : tuned_frequency ( ) ) ; // Retune
}
2023-03-22 03:46:58 -04:00
2020-06-07 19:23:44 -04:00
void SystemStatusView : : on_speaker ( ) {
2023-05-18 16:16:05 -04:00
if ( ! portapack : : speaker_mode ) {
portapack : : set_speaker_mode ( true ) ;
button_speaker . set_foreground ( Color : : green ( ) ) ;
button_speaker . set_bitmap ( & bitmap_icon_speaker ) ;
} else {
portapack : : set_speaker_mode ( false ) ;
button_speaker . set_foreground ( Color : : light_grey ( ) ) ;
button_speaker . set_bitmap ( & bitmap_icon_speaker_mute ) ;
}
}
2020-06-07 19:23:44 -04:00
2016-12-09 12:21:47 -05:00
void SystemStatusView : : on_stealth ( ) {
2023-05-18 16:16:05 -04:00
bool mode = not portapack : : persistent_memory : : stealth_mode ( ) ;
portapack : : persistent_memory : : set_stealth_mode ( mode ) ;
2018-02-22 02:04:19 -05:00
2023-05-18 16:16:05 -04:00
button_stealth . set_foreground ( mode ? Color : : green ( ) : Color : : light_grey ( ) ) ;
2016-12-09 12:21:47 -05:00
}
2018-01-07 22:47:37 -05:00
void SystemStatusView : : on_bias_tee ( ) {
2023-05-24 00:22:30 -04:00
if ( ! portapack : : get_antenna_bias ( ) ) {
2023-05-18 16:16:05 -04: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 00:22:30 -04: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 16:16:05 -04:00
refresh ( ) ;
}
2018-01-07 22:47:37 -05:00
}
2017-09-20 02:50:59 -04:00
/*void SystemStatusView::on_textentry() {
2023-05-18 16:16:05 -04: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 02:50:59 -04:00
} */
2016-05-29 06:06:47 -04:00
2016-02-19 00:35:46 -05:00
void SystemStatusView : : on_camera ( ) {
2023-05-18 16:16:05 -04:00
ensure_directory ( " SCREENSHOTS " ) ;
auto path = next_filename_matching_pattern ( u " SCREENSHOTS/SCR_????.PNG " ) ;
2023-05-12 14:08:07 -04:00
2023-05-18 16:16:05 -04:00
if ( path . empty ( ) ) {
return ;
}
2016-04-20 13:22:05 -04:00
2023-05-18 16:16:05 -04:00
PNGWriter png ;
auto create_error = png . create ( path ) ;
if ( create_error . is_valid ( ) ) {
return ;
}
2016-02-19 18:34:02 -05:00
2023-05-18 16:16:05 -04: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 00:35:46 -05:00
}
2020-09-16 07:27:56 -04:00
void SystemStatusView : : on_clk ( ) {
2023-05-18 16:16:05 -04: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 07:27:56 -04:00
}
2020-08-01 21:55:09 -04:00
void SystemStatusView : : on_title ( ) {
2023-05-18 16:16:05 -04:00
if ( nav_ . is_top ( ) )
nav_ . push < AboutView > ( ) ;
else
nav_ . pop ( ) ;
2020-08-01 21:55:09 -04:00
}
2020-08-05 01:03:51 -04:00
/* Information View *****************************************************/
InformationView : : InformationView (
2023-05-18 16:16:05 -04: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-01 21:55:09 -04:00
}
2021-05-16 05:41:09 -04:00
void InformationView : : refresh ( ) {
2023-05-18 16:16:05 -04: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 05:41:09 -04:00
}
2015-07-08 11:39:24 -04:00
/* Navigation ************************************************************/
2016-01-31 03:34:24 -05:00
bool NavigationView : : is_top ( ) const {
2023-05-18 16:16:05 -04:00
return view_stack . size ( ) = = 1 ;
2015-07-08 11:39:24 -04:00
}
2016-01-31 03:34:24 -05:00
View * NavigationView : : push_view ( std : : unique_ptr < View > new_view ) {
2023-05-18 16:16:05 -04:00
free_view ( ) ;
2016-01-31 03:34:24 -05:00
2023-05-18 16:16:05 -04:00
const auto p = new_view . get ( ) ;
view_stack . emplace_back ( std : : move ( new_view ) ) ;
2016-01-31 03:34:24 -05:00
2023-05-18 16:16:05 -04:00
update_view ( ) ;
2016-01-31 03:34:24 -05:00
2023-05-18 16:16:05 -04:00
return p ;
2015-07-08 11:39:24 -04:00
}
void NavigationView : : pop ( ) {
2023-05-18 16:16:05 -04:00
if ( view ( ) = = modal_view ) {
modal_view = nullptr ;
}
2016-05-17 12:33:16 -04:00
2023-05-18 16:16:05 -04:00
// Can't pop last item from stack.
if ( view_stack . size ( ) > 1 ) {
free_view ( ) ;
2016-01-31 03:34:24 -05:00
2023-05-18 16:16:05 -04:00
view_stack . pop_back ( ) ;
2021-05-16 05:41:09 -04:00
2023-05-18 16:16:05 -04:00
update_view ( ) ;
}
2015-07-08 11:39:24 -04:00
}
2016-12-06 07:31:38 -05:00
void NavigationView : : pop_modal ( ) {
2023-05-18 16:16:05 -04:00
if ( view ( ) = = modal_view ) {
modal_view = nullptr ;
}
2016-12-06 07:31:38 -05:00
2023-05-18 16:16:05 -04:00
// Pop modal view + underlying app view
if ( view_stack . size ( ) > 2 ) {
free_view ( ) ;
view_stack . pop_back ( ) ;
free_view ( ) ;
view_stack . pop_back ( ) ;
2016-12-06 07:31:38 -05:00
2023-05-18 16:16:05 -04:00
update_view ( ) ;
}
2016-12-06 07:31:38 -05:00
}
2016-05-17 13:15:34 -04:00
void NavigationView : : display_modal (
2023-05-18 16:16:05 -04:00
const std : : string & title ,
const std : : string & message ) {
display_modal ( title , message , INFO , nullptr ) ;
2016-12-06 07:31:38 -05:00
}
void NavigationView : : display_modal (
2023-05-18 16:16:05 -04: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 12:33:16 -04:00
}
2016-01-31 03:34:24 -05:00
void NavigationView : : free_view ( ) {
2023-05-18 16:16:05 -04:00
remove_child ( view ( ) ) ;
2015-07-08 11:39:24 -04:00
}
2016-01-31 03:34:24 -05:00
void NavigationView : : update_view ( ) {
2023-05-18 16:16:05 -04:00
const auto new_view = view_stack . back ( ) . get ( ) ;
add_child ( new_view ) ;
new_view - > set_parent_rect ( { { 0 , 0 } , size ( ) } ) ;
2015-07-08 11:39:24 -04:00
2023-05-18 16:16:05 -04:00
focus ( ) ;
set_dirty ( ) ;
if ( on_view_changed ) {
on_view_changed ( * new_view ) ;
}
2016-01-31 03:34:24 -05:00
}
2015-07-08 11:39:24 -04:00
2016-01-31 03:34:24 -05:00
Widget * NavigationView : : view ( ) const {
2023-05-18 16:16:05 -04:00
return children_ . empty ( ) ? nullptr : children_ [ 0 ] ;
2015-07-08 11:39:24 -04:00
}
void NavigationView : : focus ( ) {
2023-05-18 16:16:05 -04:00
if ( view ( ) ) {
view ( ) - > focus ( ) ;
}
2015-07-08 11:39:24 -04:00
}
2017-05-25 16:36:30 -04:00
/* ReceiversMenuView *****************************************************/
2016-01-31 03:34:24 -05:00
2017-05-25 16:36:30 -04:00
ReceiversMenuView : : ReceiversMenuView ( NavigationView & nav ) {
2023-05-18 16:16:05 -04: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 01:41:55 -05:00
}
2017-05-25 16:36:30 -04:00
/* TransmittersMenuView **************************************************/
TransmittersMenuView : : TransmittersMenuView ( NavigationView & nav ) {
2023-05-18 16:16:05 -04: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 00:39:22 -04:00
{ " Playlist " , ui : : Color : : green ( ) , & bitmap_icon_scanner , [ & nav ] ( ) { nav . push < PlaylistView > ( ) ; } } ,
2023-05-18 16:16:05 -04: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 03:34:24 -05:00
}
2017-05-25 16:36:30 -04:00
/* UtilitiesMenuView *****************************************************/
2016-12-06 07:31:38 -05:00
2017-05-25 16:36:30 -04:00
UtilitiesMenuView : : UtilitiesMenuView ( NavigationView & nav ) {
2023-05-18 16:16:05 -04: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 16:39:35 -04:00
{ " Notepad " , ui : : Color : : dark_cyan ( ) , & bitmap_icon_notepad , [ & nav ] ( ) { nav . push < TextEditorView > ( ) ; } } ,
2023-05-18 16:16:05 -04: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 07:31:38 -05:00
}
2017-05-25 16:36:30 -04:00
2015-07-08 11:39:24 -04:00
/* SystemMenuView ********************************************************/
2016-12-25 19:31:38 -05:00
void SystemMenuView : : hackrf_mode ( NavigationView & nav ) {
2023-05-18 16:16:05 -04: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-25 19:31:38 -05:00
}
2015-07-08 11:39:24 -04:00
SystemMenuView : : SystemMenuView ( NavigationView & nav ) {
2023-05-18 16:16:05 -04: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 11:39:24 -04:00
}
/* SystemView ************************************************************/
2023-05-18 16:16:05 -04:00
static constexpr ui : : Style style_default {
. font = ui : : font : : fixed_8x16 ,
. background = ui : : Color : : black ( ) ,
. foreground = ui : : Color : : white ( ) } ;
2015-07-08 11:39:24 -04:00
SystemView : : SystemView (
2023-05-18 16:16:05 -04:00
Context & context ,
const Rect parent_rect )
: View { parent_rect } ,
context_ ( context ) {
set_style ( & style_default ) ;
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 > ( ) ;
File pmem_flag_file_handle ;
std : : string pmem_flag_file = " /SETTINGS/PMEM_FILEFLAG " ;
auto result = pmem_flag_file_handle . open ( pmem_flag_file ) ;
if ( ! result . is_valid ( ) ) {
portapack : : persistent_memory : : load_persistent_settings_from_file ( " SETTINGS/pmem_settings " ) ;
}
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 11:39:24 -04:00
}
Context & SystemView : : context ( ) const {
2023-05-18 16:16:05 -04:00
return context_ ;
2015-07-08 11:39:24 -04:00
}
2023-04-23 10:21:33 -04:00
void SystemView : : toggle_overlay ( ) {
2023-05-18 16:16:05 -04: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 10:21:33 -04:00
}
void SystemView : : paint_overlay ( ) {
2023-05-18 16:16:05 -04: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 13:52:38 -04:00
2023-05-18 16:16:05 -04:00
last_paint_state = ! last_paint_state ;
this - > overlay . set_dirty ( ) ;
}
2023-04-23 10:21:33 -04:00
}
2016-02-05 11:40:14 -05:00
/* ***********************************************************************/
void BMPView : : focus ( ) {
2023-05-18 16:16:05 -04:00
button_done . focus ( ) ;
2016-02-05 11:40:14 -05:00
}
BMPView : : BMPView ( NavigationView & nav ) {
2023-05-18 16:16:05 -04:00
add_children ( { & button_done } ) ;
button_done . on_select = [ this , & nav ] ( Button & ) {
nav . pop ( ) ;
} ;
2016-02-05 11:40:14 -05:00
}
2016-12-09 12:21:47 -05:00
void BMPView : : paint ( Painter & ) {
2023-05-18 16:16:05 -04: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 11:40:14 -05:00
}
2015-07-08 11:39:24 -04:00
/* NotImplementedView ****************************************************/
2020-05-11 05:07:45 -04:00
/*NotImplementedView::NotImplementedView(NavigationView& nav) {
2023-05-18 16:16:05 -04:00
button_done . on_select = [ & nav ] ( Button & ) {
nav . pop ( ) ;
} ;
2015-07-08 11:39:24 -04:00
2023-05-18 16:16:05 -04:00
add_children ( {
& text_title ,
& button_done ,
} ) ;
2015-07-08 11:39:24 -04:00
}
void NotImplementedView : : focus ( ) {
2023-05-18 16:16:05 -04:00
button_done . focus ( ) ;
2020-05-11 05:07:45 -04:00
} */
2015-07-08 11:39:24 -04:00
2016-05-13 00:58:54 -04:00
/* ModalMessageView ******************************************************/
2016-12-09 12:21:47 -05:00
2016-05-17 13:15:34 -04:00
ModalMessageView : : ModalMessageView (
2023-05-18 16:16:05 -04: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 16:39:35 -04:00
button_ok . on_select = [ this , & nav ] ( Button & ) {
if ( on_choice_ )
on_choice_ ( true ) ; // Assumes handler will pop.
else
nav . pop ( ) ;
2023-05-18 16:16:05 -04: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 00:58:54 -04:00
}
2017-02-07 14:54:18 -05:00
void ModalMessageView : : paint ( Painter & painter ) {
2023-05-18 16:16:05 -04: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 02:45:33 -04:00
}
2016-05-13 00:58:54 -04:00
void ModalMessageView : : focus ( ) {
2023-05-18 16:16:05 -04:00
if ( ( type_ = = YESNO ) | | ( type_ = = YESCANCEL ) ) {
button_yes . focus ( ) ;
} else {
button_ok . focus ( ) ;
}
2016-05-13 00:58:54 -04:00
}
2015-07-08 11:39:24 -04:00
} /* namespace ui */