mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-01-09 14:53:38 +00:00
app manager (#2442)
* fix unset autostart * clean up - add comments to prevent misleading * move the app to external and with necessary changes * replace autostart app
This commit is contained in:
parent
bad57d1391
commit
af362600ef
@ -92,6 +92,9 @@ void ExternalModuleView::on_tick_second() {
|
|||||||
case app_location_t::TX:
|
case app_location_t::TX:
|
||||||
btnText += " (TX)";
|
btnText += " (TX)";
|
||||||
break;
|
break;
|
||||||
|
case app_location_t::SETTINGS:
|
||||||
|
btnText += " (Settings)";
|
||||||
|
break;
|
||||||
case app_location_t::DEBUG:
|
case app_location_t::DEBUG:
|
||||||
btnText += " (Debug)";
|
btnText += " (Debug)";
|
||||||
break;
|
break;
|
||||||
|
@ -53,6 +53,8 @@ namespace fs = std::filesystem;
|
|||||||
#include "i2cdevmanager.hpp"
|
#include "i2cdevmanager.hpp"
|
||||||
#include "i2cdev_max17055.hpp"
|
#include "i2cdev_max17055.hpp"
|
||||||
|
|
||||||
|
#include "file_reader.hpp"
|
||||||
|
|
||||||
extern ui::SystemView* system_view_ptr;
|
extern ui::SystemView* system_view_ptr;
|
||||||
|
|
||||||
namespace pmem = portapack::persistent_memory;
|
namespace pmem = portapack::persistent_memory;
|
||||||
@ -975,67 +977,6 @@ void SetMenuColorView::focus() {
|
|||||||
button_save.focus();
|
button_save.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SetAutoStartView ************************************/
|
|
||||||
|
|
||||||
SetAutostartView::SetAutostartView(NavigationView& nav) {
|
|
||||||
add_children({&labels,
|
|
||||||
&button_save,
|
|
||||||
&button_cancel,
|
|
||||||
&button_reset,
|
|
||||||
&options});
|
|
||||||
|
|
||||||
button_save.on_select = [&nav, this](Button&) {
|
|
||||||
autostart_app = "";
|
|
||||||
if (selected != 0) {
|
|
||||||
auto it = full_app_list.find(selected);
|
|
||||||
if (it != full_app_list.end())
|
|
||||||
autostart_app = it->second;
|
|
||||||
}
|
|
||||||
nav.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
button_cancel.on_select = [&nav, this](Button&) {
|
|
||||||
nav.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
button_reset.on_select = [this](Button&) {
|
|
||||||
selected = 0;
|
|
||||||
options.set_selected_index(0);
|
|
||||||
autostart_app = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
// options
|
|
||||||
i = 0;
|
|
||||||
OptionsField::option_t o{"-none-", i};
|
|
||||||
opts.emplace_back(o);
|
|
||||||
for (auto& app : NavigationView::appList) {
|
|
||||||
if (app.id == nullptr) continue;
|
|
||||||
i++;
|
|
||||||
o = {app.displayName, i};
|
|
||||||
opts.emplace_back(o);
|
|
||||||
full_app_list.emplace(i, app.id);
|
|
||||||
if (autostart_app == app.id) selected = i;
|
|
||||||
}
|
|
||||||
ExternalItemsMenuLoader::load_all_external_items_callback([this](ui::AppInfoConsole& app) {
|
|
||||||
if (app.appCallName == nullptr) return;
|
|
||||||
i++;
|
|
||||||
OptionsField::option_t o = {app.appFriendlyName, i};
|
|
||||||
opts.emplace_back(o);
|
|
||||||
full_app_list.emplace(i, app.appCallName);
|
|
||||||
if (autostart_app == app.appCallName) selected = i;
|
|
||||||
});
|
|
||||||
|
|
||||||
options.set_options(opts);
|
|
||||||
options.on_change = [this](size_t, OptionsField::value_t v) {
|
|
||||||
selected = v;
|
|
||||||
};
|
|
||||||
options.set_selected_index(selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetAutostartView::focus() {
|
|
||||||
options.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SetThemeView ************************************/
|
/* SetThemeView ************************************/
|
||||||
|
|
||||||
SetThemeView::SetThemeView(NavigationView& nav) {
|
SetThemeView::SetThemeView(NavigationView& nav) {
|
||||||
@ -1117,9 +1058,12 @@ SettingsMenuView::SettingsMenuView(NavigationView& nav)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SettingsMenuView::on_populate() {
|
void SettingsMenuView::on_populate() {
|
||||||
if (pmem::show_gui_return_icon()) {
|
const bool return_icon = pmem::show_gui_return_icon();
|
||||||
|
|
||||||
|
if (return_icon) {
|
||||||
add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}});
|
add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}});
|
||||||
}
|
}
|
||||||
|
|
||||||
add_items({
|
add_items({
|
||||||
{"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push<AppSettingsView>(); }},
|
{"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push<AppSettingsView>(); }},
|
||||||
{"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [this]() { nav_.push<SetAudioView>(); }},
|
{"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [this]() { nav_.push<SetAudioView>(); }},
|
||||||
@ -1138,9 +1082,11 @@ void SettingsMenuView::on_populate() {
|
|||||||
{"Display", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push<SetDisplayView>(); }},
|
{"Display", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push<SetDisplayView>(); }},
|
||||||
{"Menu Color", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push<SetMenuColorView>(); }},
|
{"Menu Color", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push<SetMenuColorView>(); }},
|
||||||
{"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetThemeView>(); }},
|
{"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetThemeView>(); }},
|
||||||
{"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetAutostartView>(); }},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (battery::BatteryManagement::isDetected()) add_item({"Battery", ui::Color::dark_cyan(), &bitmap_icon_batt_icon, [this]() { nav_.push<SetBatteryView>(); }});
|
if (battery::BatteryManagement::isDetected()) add_item({"Battery", ui::Color::dark_cyan(), &bitmap_icon_batt_icon, [this]() { nav_.push<SetBatteryView>(); }});
|
||||||
|
|
||||||
|
add_external_items(nav_, app_location_t::SETTINGS, *this, return_icon ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -888,47 +888,6 @@ class SetMenuColorView : public View {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class SetAutostartView : public View {
|
|
||||||
public:
|
|
||||||
SetAutostartView(NavigationView& nav);
|
|
||||||
|
|
||||||
void focus() override;
|
|
||||||
|
|
||||||
std::string title() const override { return "Autostart"; };
|
|
||||||
|
|
||||||
private:
|
|
||||||
int32_t i = 0;
|
|
||||||
std::string autostart_app{""};
|
|
||||||
OptionsField::options_t opts{};
|
|
||||||
std::map<int32_t, std::string> full_app_list{}; // looking table
|
|
||||||
int32_t selected = 0;
|
|
||||||
SettingsStore nav_setting{
|
|
||||||
"nav"sv,
|
|
||||||
{{"autostart_app"sv, &autostart_app}}};
|
|
||||||
Labels labels{
|
|
||||||
{{1 * 8, 1 * 16}, "Select app to start on boot", Theme::getInstance()->fg_light->foreground},
|
|
||||||
{{2 * 8, 2 * 16}, "(an SD Card is required)", Theme::getInstance()->fg_light->foreground}};
|
|
||||||
|
|
||||||
Button button_save{
|
|
||||||
{2 * 8, 16 * 16, 12 * 8, 32},
|
|
||||||
"Save"};
|
|
||||||
|
|
||||||
OptionsField options{
|
|
||||||
{0 * 8, 4 * 16},
|
|
||||||
screen_width / 8,
|
|
||||||
{},
|
|
||||||
true};
|
|
||||||
|
|
||||||
Button button_cancel{
|
|
||||||
{16 * 8, 16 * 16, 12 * 8, 32},
|
|
||||||
"Cancel",
|
|
||||||
};
|
|
||||||
|
|
||||||
Button button_reset{
|
|
||||||
{2 * 8, 6 * 16, screen_width - 4 * 8, 32},
|
|
||||||
"Reset"};
|
|
||||||
};
|
|
||||||
|
|
||||||
class SetThemeView : public View {
|
class SetThemeView : public View {
|
||||||
public:
|
public:
|
||||||
SetThemeView(NavigationView& nav);
|
SetThemeView(NavigationView& nav);
|
||||||
@ -1012,6 +971,7 @@ class SettingsMenuView : public BtnGridView {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
|
|
||||||
void on_populate() override;
|
void on_populate() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
84
firmware/application/external/app_manager/main.cpp
vendored
Normal file
84
firmware/application/external/app_manager/main.cpp
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Bernd Herzog
|
||||||
|
*
|
||||||
|
* 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.hpp"
|
||||||
|
#include "ui_app_manager.hpp"
|
||||||
|
#include "ui_navigation.hpp"
|
||||||
|
#include "external_app.hpp"
|
||||||
|
|
||||||
|
namespace ui::external_app::app_manager {
|
||||||
|
void initialize_app(ui::NavigationView& nav) {
|
||||||
|
nav.push<AppManagerView>();
|
||||||
|
}
|
||||||
|
} // namespace ui::external_app::app_manager
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
__attribute__((section(".external_app.app_app_manager.application_information"), used)) application_information_t _application_information_app_manager = {
|
||||||
|
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||||
|
/*.externalAppEntry = */ ui::external_app::app_manager::initialize_app,
|
||||||
|
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||||
|
/*.app_version = */ VERSION_MD5,
|
||||||
|
|
||||||
|
/*.app_name = */ "AppManager",
|
||||||
|
/*.bitmap_data = */ {
|
||||||
|
0xE0,
|
||||||
|
0x00,
|
||||||
|
0x10,
|
||||||
|
0x01,
|
||||||
|
0x10,
|
||||||
|
0x01,
|
||||||
|
0x1F,
|
||||||
|
0x1F,
|
||||||
|
0x01,
|
||||||
|
0x10,
|
||||||
|
0x01,
|
||||||
|
0x10,
|
||||||
|
0x01,
|
||||||
|
0x10,
|
||||||
|
0x01,
|
||||||
|
0x70,
|
||||||
|
0x01,
|
||||||
|
0x80,
|
||||||
|
0x01,
|
||||||
|
0x80,
|
||||||
|
0x01,
|
||||||
|
0x80,
|
||||||
|
0x01,
|
||||||
|
0x70,
|
||||||
|
0xE1,
|
||||||
|
0x10,
|
||||||
|
0x11,
|
||||||
|
0x11,
|
||||||
|
0x11,
|
||||||
|
0x11,
|
||||||
|
0x1F,
|
||||||
|
0x1F,
|
||||||
|
|
||||||
|
},
|
||||||
|
/*.icon_color = */ ui::Color::cyan().v,
|
||||||
|
/*.menu_location = */ app_location_t::SETTINGS,
|
||||||
|
/*.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
|
||||||
|
};
|
||||||
|
}
|
275
firmware/application/external/app_manager/ui_app_manager.cpp
vendored
Normal file
275
firmware/application/external/app_manager/ui_app_manager.cpp
vendored
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* copyleft spammingdramaqueen
|
||||||
|
*
|
||||||
|
* 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_app_manager.hpp"
|
||||||
|
#include "ui_navigation.hpp"
|
||||||
|
#include "ui_external_items_menu_loader.hpp"
|
||||||
|
|
||||||
|
#include "file.hpp"
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
#include "string_format.hpp"
|
||||||
|
|
||||||
|
#include "file_reader.hpp"
|
||||||
|
|
||||||
|
using namespace portapack;
|
||||||
|
|
||||||
|
namespace ui::external_app::app_manager {
|
||||||
|
|
||||||
|
/* AppManagerView **************************************/
|
||||||
|
/* | inner apps | external apps |
|
||||||
|
* ------------------------------
|
||||||
|
* | id | appCallName |
|
||||||
|
* | displayName|appFriendlyName|
|
||||||
|
*/
|
||||||
|
AppManagerView::AppManagerView(NavigationView& nav)
|
||||||
|
: nav_{nav} {
|
||||||
|
add_children({&labels,
|
||||||
|
&menu_view,
|
||||||
|
&text_app_info,
|
||||||
|
&button_hide_unhide,
|
||||||
|
&button_clean_hide,
|
||||||
|
&button_set_cancel_autostart,
|
||||||
|
&button_clean_autostart});
|
||||||
|
|
||||||
|
menu_view.set_parent_rect({0, 2 * 8, screen_width, 24 * 8});
|
||||||
|
|
||||||
|
menu_view.on_highlight = [this]() {
|
||||||
|
if (menu_view.highlighted_index() >= app_list_index) {
|
||||||
|
text_app_info.set("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string info;
|
||||||
|
auto app_name = get_app_info(menu_view.highlighted_index(), true);
|
||||||
|
auto app_id = get_app_info(menu_view.highlighted_index(), false);
|
||||||
|
|
||||||
|
info += "Hidden:";
|
||||||
|
|
||||||
|
if (is_blacklisted(app_name)) {
|
||||||
|
info += "Yes ";
|
||||||
|
} else {
|
||||||
|
info += "No ";
|
||||||
|
}
|
||||||
|
|
||||||
|
info += "Autostart:";
|
||||||
|
if (is_autostart_app(app_id)) {
|
||||||
|
info += "Yes";
|
||||||
|
} else {
|
||||||
|
info += "No";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.empty()) {
|
||||||
|
info = "Highlight an app";
|
||||||
|
}
|
||||||
|
|
||||||
|
text_app_info.set(info);
|
||||||
|
};
|
||||||
|
|
||||||
|
button_hide_unhide.on_select = [this](Button&) {
|
||||||
|
hide_unhide_app();
|
||||||
|
refresh_list();
|
||||||
|
};
|
||||||
|
|
||||||
|
button_clean_hide.on_select = [this](Button&) {
|
||||||
|
clean_blacklist();
|
||||||
|
refresh_list();
|
||||||
|
};
|
||||||
|
|
||||||
|
button_set_cancel_autostart.on_select = [this](Button&) {
|
||||||
|
set_unset_autostart_app();
|
||||||
|
refresh_list();
|
||||||
|
};
|
||||||
|
|
||||||
|
button_clean_autostart.on_select = [this](Button&) {
|
||||||
|
unset_auto_start();
|
||||||
|
refresh_list();
|
||||||
|
};
|
||||||
|
|
||||||
|
refresh_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::refresh_list() {
|
||||||
|
auto previous_cursor_index = menu_view.highlighted_index();
|
||||||
|
app_list_index = 0;
|
||||||
|
menu_view.clear();
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
auto padding = [](const std::string& str) {
|
||||||
|
return str.length() < 25 ? std::string(25 - str.length(), ' ') + '' : "";
|
||||||
|
// that weird char is a icon in portapack's font base that looks like a switch, which i use to indicate the auto start
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& app : NavigationView::appList) {
|
||||||
|
if (app.id == nullptr) continue;
|
||||||
|
|
||||||
|
app_list_index++;
|
||||||
|
|
||||||
|
menu_view.add_item({app.displayName + std::string(is_autostart_app(app.id) ? padding(app.displayName) : ""),
|
||||||
|
app.iconColor,
|
||||||
|
app.icon,
|
||||||
|
[this, app_id = std::string(app.id)](KeyEvent) {
|
||||||
|
button_hide_unhide.focus();
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalItemsMenuLoader::load_all_external_items_callback([this, &index, &padding](ui::AppInfoConsole& app) {
|
||||||
|
if (app.appCallName == nullptr) return;
|
||||||
|
|
||||||
|
app_list_index++;
|
||||||
|
|
||||||
|
menu_view.add_item({app.appFriendlyName + std::string(is_autostart_app(app.appCallName) ? padding(app.appFriendlyName) : ""),
|
||||||
|
ui::Color::light_grey(),
|
||||||
|
&bitmap_icon_sdcard,
|
||||||
|
[this, app_id = std::string(app.appCallName)](KeyEvent) {
|
||||||
|
button_hide_unhide.focus();
|
||||||
|
}});
|
||||||
|
});
|
||||||
|
|
||||||
|
menu_view.set_highlighted(previous_cursor_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::focus() {
|
||||||
|
menu_view.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::hide_app() {
|
||||||
|
std::vector<std::string> blacklist;
|
||||||
|
get_blacklist(blacklist);
|
||||||
|
|
||||||
|
blacklist.push_back(get_app_info(menu_view.highlighted_index(), true));
|
||||||
|
write_blacklist(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::unhide_app() {
|
||||||
|
std::vector<std::string> blacklist;
|
||||||
|
get_blacklist(blacklist);
|
||||||
|
blacklist.erase(std::remove(blacklist.begin(), blacklist.end(), get_app_info(menu_view.highlighted_index(), true)), blacklist.end());
|
||||||
|
write_blacklist(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::hide_unhide_app() {
|
||||||
|
if (is_blacklisted(get_app_info(menu_view.highlighted_index(), true)))
|
||||||
|
unhide_app();
|
||||||
|
else
|
||||||
|
hide_app();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::get_blacklist(std::vector<std::string>& blacklist) {
|
||||||
|
File f;
|
||||||
|
|
||||||
|
auto error = f.open(u"SETTINGS/blacklist");
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto reader = FileLineReader(f);
|
||||||
|
for (const auto& line : reader) {
|
||||||
|
if (line.length() == 0 || line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
blacklist.push_back(trim(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::write_blacklist(const std::vector<std::string>& blacklist) {
|
||||||
|
File f;
|
||||||
|
auto error = f.create(u"SETTINGS/blacklist");
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const auto& app_name : blacklist) {
|
||||||
|
auto line = app_name + "\n";
|
||||||
|
f.write(line.c_str(), line.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::clean_blacklist() {
|
||||||
|
std::vector<std::string> blacklist = {};
|
||||||
|
write_blacklist(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppManagerView::is_blacklisted(const std::string& app_name) {
|
||||||
|
std::vector<std::string> blacklist;
|
||||||
|
get_blacklist(blacklist);
|
||||||
|
return std::find(blacklist.begin(), blacklist.end(), app_name) != blacklist.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::set_auto_start() {
|
||||||
|
auto app_index = menu_view.highlighted_index();
|
||||||
|
if (app_index >= app_list_index) return;
|
||||||
|
|
||||||
|
auto id_aka_app_call_name = get_app_info(app_index, false);
|
||||||
|
|
||||||
|
autostart_app = id_aka_app_call_name;
|
||||||
|
|
||||||
|
refresh_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::unset_auto_start() {
|
||||||
|
autostart_app = "";
|
||||||
|
refresh_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppManagerView::set_unset_autostart_app() {
|
||||||
|
auto app_index = menu_view.highlighted_index();
|
||||||
|
if (app_index >= app_list_index) return;
|
||||||
|
|
||||||
|
auto id_aka_friendly_name = get_app_info(app_index, false);
|
||||||
|
|
||||||
|
if (is_autostart_app(id_aka_friendly_name))
|
||||||
|
unset_auto_start();
|
||||||
|
else
|
||||||
|
set_auto_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppManagerView::is_autostart_app(const char* id_aka_friendly_name) {
|
||||||
|
return autostart_app == std::string(id_aka_friendly_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppManagerView::is_autostart_app(const std::string& id_aka_friendly_name) {
|
||||||
|
return autostart_app == id_aka_friendly_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AppManagerView::get_app_info(uint16_t index, bool is_display_name) {
|
||||||
|
size_t current_index = 0;
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
for (auto& app : NavigationView::appList) {
|
||||||
|
if (app.id == nullptr) continue;
|
||||||
|
if (current_index == index) {
|
||||||
|
return is_display_name ? std::string(app.displayName) : std::string(app.id);
|
||||||
|
}
|
||||||
|
current_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalItemsMenuLoader::load_all_external_items_callback([¤t_index, &index, &result, &is_display_name](ui::AppInfoConsole& app) {
|
||||||
|
if (app.appCallName == nullptr) return;
|
||||||
|
if (current_index == index) {
|
||||||
|
result = is_display_name ? app.appFriendlyName : app.appCallName;
|
||||||
|
}
|
||||||
|
current_index++;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ui::external_app::app_manager
|
87
firmware/application/external/app_manager/ui_app_manager.hpp
vendored
Normal file
87
firmware/application/external/app_manager/ui_app_manager.hpp
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* copyleft spammingdramaqueen
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UI_APP_MANAGER_H__
|
||||||
|
#define __UI_APP_MANAGER_H__
|
||||||
|
|
||||||
|
#include "ui_navigation.hpp"
|
||||||
|
|
||||||
|
namespace ui::external_app::app_manager {
|
||||||
|
|
||||||
|
class AppManagerView : public View {
|
||||||
|
public:
|
||||||
|
AppManagerView(NavigationView& nav);
|
||||||
|
std::string title() const override { return "AppMan"; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
NavigationView& nav_;
|
||||||
|
std::string autostart_app{""};
|
||||||
|
SettingsStore nav_setting{
|
||||||
|
"nav"sv,
|
||||||
|
{{"autostart_app"sv, &autostart_app}}};
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
void refresh_list();
|
||||||
|
uint16_t app_list_index{0};
|
||||||
|
|
||||||
|
Labels labels{
|
||||||
|
{{0 * 8, 0 * 16}, "App list:", Theme::getInstance()->fg_light->foreground}};
|
||||||
|
|
||||||
|
MenuView menu_view{};
|
||||||
|
|
||||||
|
Text text_app_info{
|
||||||
|
{0, 27 * 8, screen_width, 16},
|
||||||
|
"Highlight an app"};
|
||||||
|
|
||||||
|
Button button_hide_unhide{
|
||||||
|
{0, 29 * 8, screen_width / 2 - 1, 32},
|
||||||
|
"Hide/Show"};
|
||||||
|
|
||||||
|
Button button_clean_hide{
|
||||||
|
{screen_width / 2 + 2, 29 * 8, screen_width / 2 - 2, 32},
|
||||||
|
"Clean Hidden"};
|
||||||
|
|
||||||
|
Button button_set_cancel_autostart{
|
||||||
|
{0, screen_height - 32 - 16, screen_width / 2 - 1, 32},
|
||||||
|
"Set Autostart"};
|
||||||
|
|
||||||
|
Button button_clean_autostart{
|
||||||
|
{screen_width / 2 + 2, screen_height - 32 - 16, screen_width / 2 - 2, 32},
|
||||||
|
"Del Autostart"};
|
||||||
|
|
||||||
|
std::string get_app_info(uint16_t index, bool is_display_name);
|
||||||
|
void get_blacklist(std::vector<std::string>& blacklist);
|
||||||
|
void write_blacklist(const std::vector<std::string>& blacklist);
|
||||||
|
bool is_blacklisted(const std::string& app_display_name);
|
||||||
|
void hide_app();
|
||||||
|
void unhide_app();
|
||||||
|
void hide_unhide_app();
|
||||||
|
void clean_blacklist();
|
||||||
|
bool is_autostart_app(const std::string& display_name);
|
||||||
|
void set_auto_start();
|
||||||
|
void unset_auto_start();
|
||||||
|
void set_unset_autostart_app();
|
||||||
|
bool is_autostart_app(const char* id_aka_app_call_name);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui::external_app::app_manager
|
||||||
|
|
||||||
|
#endif // __UI_APP_MANAGER_H__
|
5
firmware/application/external/external.cmake
vendored
5
firmware/application/external/external.cmake
vendored
@ -146,6 +146,10 @@ set(EXTCPPSRC
|
|||||||
#metronome
|
#metronome
|
||||||
external/metronome/main.cpp
|
external/metronome/main.cpp
|
||||||
external/metronome/ui_metronome.cpp
|
external/metronome/ui_metronome.cpp
|
||||||
|
|
||||||
|
#app_manager
|
||||||
|
external/app_manager/main.cpp
|
||||||
|
external/app_manager/ui_app_manager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(EXTAPPLIST
|
set(EXTAPPLIST
|
||||||
@ -184,4 +188,5 @@ set(EXTAPPLIST
|
|||||||
fmradio
|
fmradio
|
||||||
tuner
|
tuner
|
||||||
metronome
|
metronome
|
||||||
|
app_manager
|
||||||
)
|
)
|
7
firmware/application/external/external.ld
vendored
7
firmware/application/external/external.ld
vendored
@ -58,6 +58,7 @@ MEMORY
|
|||||||
ram_external_app_fmradio(rwx) : org = 0xADD10000, len = 32k
|
ram_external_app_fmradio(rwx) : org = 0xADD10000, len = 32k
|
||||||
ram_external_app_tuner(rwx) : org = 0xADD20000, len = 32k
|
ram_external_app_tuner(rwx) : org = 0xADD20000, len = 32k
|
||||||
ram_external_app_metronome(rwx) : org = 0xADD30000, len = 32k
|
ram_external_app_metronome(rwx) : org = 0xADD30000, len = 32k
|
||||||
|
ram_external_app_app_manager(rwx) : org = 0xADD40000, len = 32k
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
@ -272,4 +273,10 @@ SECTIONS
|
|||||||
KEEP(*(.external_app.app_metronome.application_information));
|
KEEP(*(.external_app.app_metronome.application_information));
|
||||||
*(*ui*external_app*metronome*);
|
*(*ui*external_app*metronome*);
|
||||||
} > ram_external_app_metronome
|
} > ram_external_app_metronome
|
||||||
|
|
||||||
|
.external_app_app_manager : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.external_app.app_app_manager.application_information));
|
||||||
|
*(*ui*external_app*app_manager*);
|
||||||
|
} > ram_external_app_app_manager
|
||||||
}
|
}
|
||||||
|
@ -760,7 +760,7 @@ void NavigationView::handle_autostart() {
|
|||||||
|
|
||||||
/* Helpers **************************************************************/
|
/* Helpers **************************************************************/
|
||||||
|
|
||||||
static void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc) {
|
void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc) {
|
||||||
for (auto& app : NavigationView::appList) {
|
for (auto& app : NavigationView::appList) {
|
||||||
if (app.menuLocation == loc) {
|
if (app.menuLocation == loc) {
|
||||||
grid.add_item({app.displayName, app.iconColor, app.icon,
|
grid.add_item({app.displayName, app.iconColor, app.icon,
|
||||||
|
@ -59,6 +59,10 @@ using namespace sd_card;
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc);
|
||||||
|
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos);
|
||||||
|
bool verify_sdcard_format();
|
||||||
|
|
||||||
enum modal_t {
|
enum modal_t {
|
||||||
INFO = 0,
|
INFO = 0,
|
||||||
YESNO,
|
YESNO,
|
||||||
|
@ -71,7 +71,8 @@ enum app_location_t : uint32_t {
|
|||||||
RX,
|
RX,
|
||||||
TX,
|
TX,
|
||||||
DEBUG,
|
DEBUG,
|
||||||
HOME
|
HOME,
|
||||||
|
SETTINGS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct standalone_application_information_t {
|
struct standalone_application_information_t {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user