Restore home menu order (#2384)

* Fix ext notice position ( No need to alter the position of the ext app notice, as there is no back button on the home screen )
* add desired position to external apps
* read and store desired location
* apply ext apps desired order
* fix memory alignment in application_information_t
This commit is contained in:
E.T.
2024-11-23 21:37:03 +01:00
committed by GitHub
parent e6a099913a
commit 69271632ae
38 changed files with 130 additions and 56 deletions

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_acars_rx.application_information"), us
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_acars */ {'P', 'A', 'C', 'A'}, /*.m4_app_tag = portapack::spi_flash::image_tag_acars */ {'P', 'A', 'C', 'A'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_adsbtx.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_adsbtx */ {'P', 'A', 'D', 'T'}, /*.m4_app_tag = portapack::spi_flash::image_tag_adsbtx */ {'P', 'A', 'D', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_afsk_rx.application_information"), use
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'F', 'R'}, /*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'F', 'R'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_analogtv.application_information"), us
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_am_tv */ {'P', 'A', 'M', 'T'}, /*.m4_app_tag = portapack::spi_flash::image_tag_am_tv */ {'P', 'A', 'M', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_audio_test.application_information"),
}, },
/*.icon_color = */ ui::Color::cyan().v, /*.icon_color = */ ui::Color::cyan().v,
/*.menu_location = */ app_location_t::DEBUG, /*.menu_location = */ app_location_t::DEBUG,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {'P', 'A', 'B', 'P'}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {'P', 'A', 'B', 'P'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_blespam.application_information"), use
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_btle_tx */ {'P', 'B', 'T', 'T'}, /*.m4_app_tag = portapack::spi_flash::image_tag_btle_tx */ {'P', 'B', 'T', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_calculator.application_information"),
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::UTILITIES, /*.menu_location = */ app_location_t::UTILITIES,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -76,6 +76,7 @@ __attribute__((section(".external_app.app_coasterp.application_information"), us
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_fsktx */ {'P', 'F', 'S', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_fsktx */ {'P', 'F', 'S', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -17,17 +17,18 @@ void initialize_app(NavigationView& nav) {
extern "C" { extern "C" {
__attribute__((section(".external_app.app_cvs_spam.application_information"), used)) application_information_t _application_information_cvs_spam = { __attribute__((section(".external_app.app_cvs_spam.application_information"), used)) application_information_t _application_information_cvs_spam = {
(uint8_t*)0x00000000, /*.memory_location = */ (uint8_t*)0x00000000,
ui::external_app::cvs_spam::initialize_app, /*.externalAppEntry = */ ui::external_app::cvs_spam::initialize_app,
CURRENT_HEADER_VERSION, /*.header_version = */ CURRENT_HEADER_VERSION,
VERSION_MD5, /*.app_version = */ VERSION_MD5,
"CVS Spam",
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*.app_name = */ "CVS Spam",
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*.bitmap_data = */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81},
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*.icon_color = */ ui::Color::red().v,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81}, /*.menu_location = */ app_location_t::TX,
ui::Color::red().v, /*.desired_menu_position = */ -1,
app_location_t::TX,
{'P', 'R', 'E', 'P'}, /*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'R', 'E', 'P'},
0x00000000}; /*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
} }

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_extsensors.application_information"),
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::DEBUG, /*.menu_location = */ app_location_t::DEBUG,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_flippertx.application_information"), u
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_ookstreaming */ {'P', 'O', 'S', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_ookstreaming */ {'P', 'O', 'S', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_font_viewer.application_information"),
}, },
/*.icon_color = */ ui::Color::cyan().v, /*.icon_color = */ ui::Color::cyan().v,
/*.menu_location = */ app_location_t::DEBUG, /*.menu_location = */ app_location_t::DEBUG,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_foxhunt_rx.application_information"),
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_am_audio */ {'P', 'A', 'M', 'A'}, /*.m4_app_tag = portapack::spi_flash::image_tag_am_audio */ {'P', 'A', 'M', 'A'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_gpssim.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_gpssim */ {'P', 'G', 'P', 'S'}, /*.m4_app_tag = portapack::spi_flash::image_tag_gpssim */ {'P', 'G', 'P', 'S'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_jammer.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_jammer */ {'P', 'J', 'A', 'M'}, /*.m4_app_tag = portapack::spi_flash::image_tag_jammer */ {'P', 'J', 'A', 'M'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_keyfob.application_information"), used
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_keyfob */ {'P', 'O', 'O', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_keyfob */ {'P', 'O', 'O', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_lcr.application_information"), used))
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_afsk */ {'P', 'A', 'F', 'T'}, /*.m4_app_tag = portapack::spi_flash::image_tag_afsk */ {'P', 'A', 'F', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_lge.application_information"), used))
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_fsktx */ {'P', 'F', 'S', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_fsktx */ {'P', 'F', 'S', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_morse_tx.application_information"), us
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_tones */ {'P', 'T', 'O', 'N'}, /*.m4_app_tag = portapack::spi_flash::image_tag_tones */ {'P', 'T', 'O', 'N'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -76,6 +76,7 @@ __attribute__((section(".external_app.app_nrf_rx.application_information"), used
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_nrf_rx */ {'P', 'N', 'R', 'R'}, /*.m4_app_tag = portapack::spi_flash::image_tag_nrf_rx */ {'P', 'N', 'R', 'R'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_ook_editor.application_information"),
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_ookbrute.application_information"), us
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'}, /*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_protoview.application_information"), u
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_protoview */ {'P', 'P', 'V', 'W'}, /*.m4_app_tag = portapack::spi_flash::image_tag_protoview */ {'P', 'P', 'V', 'W'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_random_password.application_informatio
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::UTILITIES, /*.menu_location = */ app_location_t::UTILITIES,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'F', 'R'}, /*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'F', 'R'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_remote.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::HOME, /*.menu_location = */ app_location_t::HOME,
/*.desired_menu_position = */ 4,
/*.m4_app_tag = portapack::spi_flash::image_tag_replay */ {'P', 'R', 'E', 'P'}, /*.m4_app_tag = portapack::spi_flash::image_tag_replay */ {'P', 'R', 'E', 'P'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -16,12 +16,13 @@ void initialize_app(NavigationView& nav) {
extern "C" { extern "C" {
__attribute__((section(".external_app.app_shoppingcart_lock.application_information"), used)) application_information_t _application_information_shoppingcart_lock = { __attribute__((section(".external_app.app_shoppingcart_lock.application_information"), used)) application_information_t _application_information_shoppingcart_lock = {
(uint8_t*)0x00000000, /*.memory_location = */ (uint8_t*)0x00000000,
ui::external_app::shoppingcart_lock::initialize_app, /*.externalAppEntry = */ ui::external_app::shoppingcart_lock::initialize_app,
CURRENT_HEADER_VERSION, /*.header_version = */ CURRENT_HEADER_VERSION,
VERSION_MD5, /*.app_version = */ VERSION_MD5,
"Cart Lock",
{ /*.app_name = */ "Cart Lock",
/*.bitmap_data = */ {
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
@@ -55,9 +56,11 @@ __attribute__((section(".external_app.app_shoppingcart_lock.application_informat
0x7E, 0x7E,
0x00, 0x00,
}, },
ui::Color::red().v, /*.icon_color = */ ui::Color::red().v,
app_location_t::UTILITIES, /*.menu_location = */ app_location_t::UTILITIES,
{'P', 'A', 'T', 'X'}, /*.desired_menu_position = */ -1,
0x00000000,
/*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'T', 'X'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
}; };
} }

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_spainter.application_information"), us
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_spainter */ {'P', 'S', 'P', 'T'}, /*.m4_app_tag = portapack::spi_flash::image_tag_spainter */ {'P', 'S', 'P', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_sstvtx.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX, /*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_sstvtx */ {'P', 'S', 'T', 'X'}, /*.m4_app_tag = portapack::spi_flash::image_tag_sstvtx */ {'P', 'S', 'T', 'X'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_tetris.application_information"), used
}, },
/*.icon_color = */ ui::Color::orange().v, /*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::UTILITIES, /*.menu_location = */ app_location_t::UTILITIES,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_tpmsrx.application_information"), used
}, },
/*.icon_color = */ ui::Color::green().v, /*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::RX, /*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_tpms */ {'P', 'T', 'P', 'M'}, /*.m4_app_tag = portapack::spi_flash::image_tag_tpms */ {'P', 'T', 'P', 'M'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -75,6 +75,7 @@ __attribute__((section(".external_app.app_wardrivemap.application_information"),
}, },
/*.icon_color = */ ui::Color::yellow().v, /*.icon_color = */ ui::Color::yellow().v,
/*.menu_location = */ app_location_t::UTILITIES, /*.menu_location = */ app_location_t::UTILITIES,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time /*.m4_app_offset = */ 0x00000000, // will be filled at compile time

View File

@@ -118,30 +118,36 @@ void BtnGridView::clear() {
menu_item_views.clear(); menu_item_views.clear();
} }
void BtnGridView::add_items(std::initializer_list<GridItem> new_items) { void BtnGridView::add_items(std::initializer_list<GridItem> new_items, bool inhibit_update) {
for (auto item : new_items) { for (auto item : new_items) {
if (!blacklisted_app(item)) if (!blacklisted_app(item))
menu_items.push_back(item); menu_items.push_back(item);
} }
update_items(); if (!inhibit_update) {
}
void BtnGridView::add_item(GridItem new_item) {
if (!blacklisted_app(new_item)) {
menu_items.push_back(new_item);
update_items(); update_items();
} }
} }
void BtnGridView::insert_item(GridItem new_item, uint8_t position) { void BtnGridView::add_item(const GridItem& new_item, bool inhibit_update) {
if (!blacklisted_app(new_item)) {
menu_items.push_back(new_item);
if (!inhibit_update) {
update_items();
}
}
}
void BtnGridView::insert_item(const GridItem& new_item, size_t position, bool inhibit_update) {
if (!blacklisted_app(new_item)) { if (!blacklisted_app(new_item)) {
if (position < menu_items.size()) { if (position < menu_items.size()) {
auto pos_iter = menu_items.begin() + position; auto pos_iter = menu_items.begin() + position;
menu_items.insert(pos_iter, new_item); menu_items.insert(pos_iter, new_item);
update_items();
} else { } else {
menu_items.push_back(new_item); menu_items.push_back(new_item);
}
if (!inhibit_update) {
update_items(); update_items();
} }
} }

View File

@@ -59,9 +59,9 @@ class BtnGridView : public View {
~BtnGridView(); ~BtnGridView();
void add_items(std::initializer_list<GridItem> new_items); void add_items(std::initializer_list<GridItem> new_items, bool inhibit_update = false);
void add_item(GridItem new_item); void add_item(const GridItem& new_item, bool inhibit_update = false);
void insert_item(GridItem new_item, uint8_t position); void insert_item(const GridItem& new_item, size_t position, bool inhibit_update = false);
void set_max_rows(int rows); void set_max_rows(int rows);
int rows(); int rows();
void clear(); void clear();
@@ -81,12 +81,13 @@ class BtnGridView : public View {
bool on_encoder(const EncoderEvent event) override; bool on_encoder(const EncoderEvent event) override;
bool blacklisted_app(GridItem new_item); bool blacklisted_app(GridItem new_item);
void update_items();
protected: protected:
virtual void on_populate() = 0; virtual void on_populate() = 0;
private: private:
int rows_{3}; int rows_{3};
void update_items();
void on_tick_second(); void on_tick_second();
bool keep_highlight{false}; bool keep_highlight{false};

View File

@@ -97,10 +97,10 @@ namespace ui {
} }
} }
/* static */ std::vector<GridItem> ExternalItemsMenuLoader::load_external_items(app_location_t app_location, NavigationView& nav) { /* static */ std::vector<ExternalItemsMenuLoader::GridItemEx> ExternalItemsMenuLoader::load_external_items(app_location_t app_location, NavigationView& nav) {
bitmaps.clear(); bitmaps.clear();
std::vector<GridItem> external_apps; std::vector<GridItemEx> external_apps;
auto dev = (i2cdev::I2cDev_PPmod*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD); auto dev = (i2cdev::I2cDev_PPmod*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD);
@@ -121,7 +121,7 @@ namespace ui {
if (appInfo->header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION) if (appInfo->header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue; continue;
GridItem gridItem = {}; GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&appInfo->app_name[0]); gridItem.text = reinterpret_cast<char*>(&appInfo->app_name[0]);
gridItem.color = Color((uint16_t)appInfo->icon_color); gridItem.color = Color((uint16_t)appInfo->icon_color);
@@ -150,6 +150,8 @@ namespace ui {
nav.display_modal("Error", "Unable to download app."); nav.display_modal("Error", "Unable to download app.");
}; };
gridItem.desired_position = -1; // TODO: Where should we put the module's app icon? First? Last? Also configurable?
external_apps.push_back(gridItem); external_apps.push_back(gridItem);
} }
} }
@@ -180,7 +182,7 @@ namespace ui {
bool versionMatches = VERSION_MD5 == application_information.app_version; bool versionMatches = VERSION_MD5 == application_information.app_version;
GridItem gridItem = {}; GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]); gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]);
if (versionMatches) { if (versionMatches) {
@@ -195,6 +197,8 @@ namespace ui {
nav.display_modal("Error", "The .ppma file in your " + apps_dir.string() + "\nfolder can't be read. Please\nupdate your SD Card content."); nav.display_modal("Error", "The .ppma file in your " + apps_dir.string() + "\nfolder can't be read. Please\nupdate your SD Card content.");
} }
}; };
gridItem.desired_position = application_information.desired_menu_position;
} else { } else {
gridItem.color = Theme::getInstance()->fg_light->foreground; gridItem.color = Theme::getInstance()->fg_light->foreground;
@@ -203,6 +207,8 @@ namespace ui {
gridItem.on_select = [&nav]() { gridItem.on_select = [&nav]() {
nav.display_modal("Error", "The .ppma file in your " + apps_dir.string() + "\nfolder is outdated. Please\nupdate your SD Card content."); nav.display_modal("Error", "The .ppma file in your " + apps_dir.string() + "\nfolder is outdated. Please\nupdate your SD Card content.");
}; };
gridItem.desired_position = application_information.desired_menu_position;
} }
external_apps.push_back(gridItem); external_apps.push_back(gridItem);
@@ -228,7 +234,7 @@ namespace ui {
if (application_information.header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION) if (application_information.header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue; continue;
GridItem gridItem = {}; GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]); gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]);
gridItem.color = Color((uint16_t)application_information.icon_color); gridItem.color = Color((uint16_t)application_information.icon_color);
@@ -243,6 +249,8 @@ namespace ui {
} }
}; };
gridItem.desired_position = -1; // No desired position support for standalone apps yet
external_apps.push_back(gridItem); external_apps.push_back(gridItem);
} }

View File

@@ -55,7 +55,11 @@ class DynamicBitmap {
class ExternalItemsMenuLoader { class ExternalItemsMenuLoader {
public: public:
static std::vector<GridItem> load_external_items(app_location_t, NavigationView&); struct GridItemEx : GridItem {
int32_t desired_position;
};
static std::vector<GridItemEx> load_external_items(app_location_t, NavigationView&);
ExternalItemsMenuLoader() = delete; ExternalItemsMenuLoader() = delete;
static bool run_external_app(ui::NavigationView&, std::filesystem::path); static bool run_external_app(ui::NavigationView&, std::filesystem::path);
static bool run_standalone_app(ui::NavigationView&, std::filesystem::path); static bool run_standalone_app(ui::NavigationView&, std::filesystem::path);

View File

@@ -752,13 +752,16 @@ static void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc)
grid.add_item({app.displayName, app.iconColor, app.icon, grid.add_item({app.displayName, app.iconColor, app.icon,
[&nav, &app]() { [&nav, &app]() {
i2cdev::I2CDevManager::set_autoscan_interval(0); //if i navigate away from any menu, turn off autoscan i2cdev::I2CDevManager::set_autoscan_interval(0); //if i navigate away from any menu, turn off autoscan
nav.push_view(std::unique_ptr<View>(app.viewFactory->produce(nav))); }}); nav.push_view(std::unique_ptr<View>(app.viewFactory->produce(nav))); }},
true);
} }
}; };
grid.update_items();
} }
// clang-format off // clang-format off
void addExternalItems(NavigationView& nav, app_location_t location, BtnGridView& grid) { void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t notice_pos) {
auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav); auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav);
if (externalItems.empty()) { if (externalItems.empty()) {
grid.insert_item({"Notice!", grid.insert_item({"Notice!",
@@ -771,11 +774,23 @@ void addExternalItems(NavigationView& nav, app_location_t location, BtnGridView&
"see Mayhem wiki and copy apps\n" "see Mayhem wiki and copy apps\n"
"to " + apps_dir.string() + " folder of SD card."); "to " + apps_dir.string() + " folder of SD card.");
}}, }},
pmem::show_gui_return_icon() ? 1 : 0); notice_pos);
} else { } else {
std::sort(externalItems.begin(), externalItems.end(), [](const auto &a, const auto &b)
{
return a.desired_position < b.desired_position;
});
for (auto const& gridItem : externalItems) { for (auto const& gridItem : externalItems) {
grid.add_item(gridItem); if (gridItem.desired_position < 0) {
grid.add_item(gridItem, true);
} else {
grid.insert_item(gridItem, gridItem.desired_position, true);
}
} }
grid.update_items();
} }
} }
// clang-format on // clang-format on
@@ -786,13 +801,14 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav)
: nav_(nav) {} : nav_(nav) {}
void ReceiversMenuView::on_populate() { void ReceiversMenuView::on_populate() {
if (pmem::show_gui_return_icon()) { bool return_icon = pmem::show_gui_return_icon();
if (return_icon) {
add_item({"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}); add_item({"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }});
} }
add_apps(nav_, *this, RX); add_apps(nav_, *this, RX);
addExternalItems(nav_, app_location_t::RX, *this); add_external_items(nav_, app_location_t::RX, *this, return_icon ? 1 : 0);
} }
/* TransmittersMenuView **************************************************/ /* TransmittersMenuView **************************************************/
@@ -801,13 +817,14 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav)
: nav_(nav) {} : nav_(nav) {}
void TransmittersMenuView::on_populate() { void TransmittersMenuView::on_populate() {
if (pmem::show_gui_return_icon()) { bool return_icon = pmem::show_gui_return_icon();
if (return_icon) {
add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}}); add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}});
} }
add_apps(nav_, *this, TX); add_apps(nav_, *this, TX);
addExternalItems(nav_, app_location_t::TX, *this); add_external_items(nav_, app_location_t::TX, *this, return_icon ? 1 : 0);
} }
/* UtilitiesMenuView *****************************************************/ /* UtilitiesMenuView *****************************************************/
@@ -818,13 +835,14 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav)
} }
void UtilitiesMenuView::on_populate() { void UtilitiesMenuView::on_populate() {
if (pmem::show_gui_return_icon()) { bool return_icon = pmem::show_gui_return_icon();
if (return_icon) {
add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}}); add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}});
} }
add_apps(nav_, *this, UTILITIES); add_apps(nav_, *this, UTILITIES);
addExternalItems(nav_, app_location_t::UTILITIES, *this); add_external_items(nav_, app_location_t::UTILITIES, *this, return_icon ? 1 : 0);
} }
/* SystemMenuView ********************************************************/ /* SystemMenuView ********************************************************/
@@ -849,7 +867,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav)
void SystemMenuView::on_populate() { void SystemMenuView::on_populate() {
add_apps(nav_, *this, HOME); add_apps(nav_, *this, HOME);
addExternalItems(nav_, app_location_t::HOME, *this); add_external_items(nav_, app_location_t::HOME, *this, 2);
add_item({"HackRF", Theme::getInstance()->fg_cyan->foreground, &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }}); add_item({"HackRF", Theme::getInstance()->fg_cyan->foreground, &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }});
} }

View File

@@ -27,7 +27,7 @@
#include "spi_image.hpp" #include "spi_image.hpp"
#include "standalone_app.hpp" #include "standalone_app.hpp"
#define CURRENT_HEADER_VERSION 0x00000002 #define CURRENT_HEADER_VERSION 0x00000003
#define MIN_HEADER_VERSION_FOR_CHECKSUM 0x00000002 #define MIN_HEADER_VERSION_FOR_CHECKSUM 0x00000002
typedef void (*externalAppEntry_t)(ui::NavigationView& nav); typedef void (*externalAppEntry_t)(ui::NavigationView& nav);
@@ -42,6 +42,7 @@ struct application_information_t {
uint8_t bitmap_data[32]; uint8_t bitmap_data[32];
uint32_t icon_color; uint32_t icon_color;
app_location_t menu_location; app_location_t menu_location;
int32_t desired_menu_position;
portapack::spi_flash::image_tag_t m4_app_tag; portapack::spi_flash::image_tag_t m4_app_tag;
uint32_t m4_app_offset; uint32_t m4_app_offset;

View File

@@ -91,8 +91,8 @@ cmake_objcopy = sys.argv[3]
memory_location_header_position = 0 memory_location_header_position = 0
externalAppEntry_header_position = 4 externalAppEntry_header_position = 4
m4_app_tag_header_position = 72 m4_app_tag_header_position = 76
m4_app_offset_header_position = 76 m4_app_offset_header_position = 80
for external_image_prefix in sys.argv[4:]: for external_image_prefix in sys.argv[4:]:
@@ -123,7 +123,10 @@ for external_image_prefix in sys.argv[4:]:
write_image(external_application_image, "{}/{}.ppma".format(binary_dir, external_image_prefix)) write_image(external_application_image, "{}/{}.ppma".format(binary_dir, external_image_prefix))
continue continue
print(chunk_data)
chunk_tag = chunk_data.decode("utf-8") chunk_tag = chunk_data.decode("utf-8")
print(chunk_tag)
print("{}/../baseband/{}.bin".format(binary_dir, chunk_tag))
m4_image = read_image("{}/../baseband/{}.bin".format(binary_dir, chunk_tag)) m4_image = read_image("{}/../baseband/{}.bin".format(binary_dir, chunk_tag))
app_image_len = len(external_application_image) app_image_len = len(external_application_image)
external_application_image += m4_image external_application_image += m4_image