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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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,
/*.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_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,
/*.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_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,
/*.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_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,
/*.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_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,
/*.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_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,
/*.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_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,
/*.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_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,
/*.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_offset = */ 0x00000000, // will be filled at compile time

View File

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

View File

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

View File

@ -118,30 +118,36 @@ void BtnGridView::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) {
if (!blacklisted_app(item))
menu_items.push_back(item);
}
if (!inhibit_update) {
update_items();
}
}
void BtnGridView::add_item(GridItem new_item) {
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(GridItem new_item, uint8_t position) {
void BtnGridView::insert_item(const GridItem& new_item, size_t position, bool inhibit_update) {
if (!blacklisted_app(new_item)) {
if (position < menu_items.size()) {
auto pos_iter = menu_items.begin() + position;
menu_items.insert(pos_iter, new_item);
update_items();
} else {
menu_items.push_back(new_item);
}
if (!inhibit_update) {
update_items();
}
}

View File

@ -59,9 +59,9 @@ class BtnGridView : public View {
~BtnGridView();
void add_items(std::initializer_list<GridItem> new_items);
void add_item(GridItem new_item);
void insert_item(GridItem new_item, uint8_t position);
void add_items(std::initializer_list<GridItem> new_items, bool inhibit_update = false);
void add_item(const GridItem& new_item, bool inhibit_update = false);
void insert_item(const GridItem& new_item, size_t position, bool inhibit_update = false);
void set_max_rows(int rows);
int rows();
void clear();
@ -81,12 +81,13 @@ class BtnGridView : public View {
bool on_encoder(const EncoderEvent event) override;
bool blacklisted_app(GridItem new_item);
void update_items();
protected:
virtual void on_populate() = 0;
private:
int rows_{3};
void update_items();
void on_tick_second();
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();
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);
@ -121,7 +121,7 @@ namespace ui {
if (appInfo->header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue;
GridItem gridItem = {};
GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&appInfo->app_name[0]);
gridItem.color = Color((uint16_t)appInfo->icon_color);
@ -150,6 +150,8 @@ namespace ui {
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);
}
}
@ -180,7 +182,7 @@ namespace ui {
bool versionMatches = VERSION_MD5 == application_information.app_version;
GridItem gridItem = {};
GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]);
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.");
}
};
gridItem.desired_position = application_information.desired_menu_position;
} else {
gridItem.color = Theme::getInstance()->fg_light->foreground;
@ -203,6 +207,8 @@ namespace ui {
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.");
};
gridItem.desired_position = application_information.desired_menu_position;
}
external_apps.push_back(gridItem);
@ -228,7 +234,7 @@ namespace ui {
if (application_information.header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue;
GridItem gridItem = {};
GridItemEx gridItem = {};
gridItem.text = reinterpret_cast<char*>(&application_information.app_name[0]);
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);
}

View File

@ -55,7 +55,11 @@ class DynamicBitmap {
class ExternalItemsMenuLoader {
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;
static bool run_external_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,
[&nav, &app]() {
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
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);
if (externalItems.empty()) {
grid.insert_item({"Notice!",
@ -771,11 +774,23 @@ void addExternalItems(NavigationView& nav, app_location_t location, BtnGridView&
"see Mayhem wiki and copy apps\n"
"to " + apps_dir.string() + " folder of SD card.");
}},
pmem::show_gui_return_icon() ? 1 : 0);
notice_pos);
} 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) {
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
@ -786,13 +801,14 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav)
: nav_(nav) {}
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_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 **************************************************/
@ -801,13 +817,14 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav)
: nav_(nav) {}
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_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 *****************************************************/
@ -818,13 +835,14 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav)
}
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_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 ********************************************************/
@ -849,7 +867,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav)
void SystemMenuView::on_populate() {
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_); }});
}

View File

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

View File

@ -91,8 +91,8 @@ cmake_objcopy = sys.argv[3]
memory_location_header_position = 0
externalAppEntry_header_position = 4
m4_app_tag_header_position = 72
m4_app_offset_header_position = 76
m4_app_tag_header_position = 76
m4_app_offset_header_position = 80
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))
continue
print(chunk_data)
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))
app_image_len = len(external_application_image)
external_application_image += m4_image