mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-04 23:45:26 +00:00
Externalize Remote (#2370)
* externalize Remote app, disabling fileman integration (need workaround) * regenerate bitmap.hpp * added external HOME apps to HOME
This commit is contained in:
parent
4a83118557
commit
24d15c1643
@ -303,7 +303,6 @@ set(CPPSRC
|
|||||||
apps/ui_rds.cpp
|
apps/ui_rds.cpp
|
||||||
apps/ui_recon_settings.cpp
|
apps/ui_recon_settings.cpp
|
||||||
apps/ui_recon.cpp
|
apps/ui_recon.cpp
|
||||||
apps/ui_remote.cpp
|
|
||||||
apps/ui_scanner.cpp
|
apps/ui_scanner.cpp
|
||||||
apps/ui_sd_over_usb.cpp
|
apps/ui_sd_over_usb.cpp
|
||||||
apps/ui_sd_wipe.cpp
|
apps/ui_sd_wipe.cpp
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "ui_fileman.hpp"
|
#include "ui_fileman.hpp"
|
||||||
#include "ui_playlist.hpp"
|
#include "ui_playlist.hpp"
|
||||||
#include "ui_remote.hpp"
|
|
||||||
#include "ui_ss_viewer.hpp"
|
#include "ui_ss_viewer.hpp"
|
||||||
#include "ui_bmp_file_viewer.hpp"
|
#include "ui_bmp_file_viewer.hpp"
|
||||||
#include "ui_text_editor.hpp"
|
#include "ui_text_editor.hpp"
|
||||||
@ -704,10 +703,11 @@ bool FileManagerView::handle_file_open() {
|
|||||||
|
|
||||||
reload_current(false);
|
reload_current(false);
|
||||||
return true;
|
return true;
|
||||||
} else if (path_iequal(rem_ext, ext)) {
|
}
|
||||||
|
/*else if (path_iequal(rem_ext, ext)) {
|
||||||
nav_.push<RemoteView>(path);
|
nav_.push<RemoteView>(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
6
firmware/application/external/external.cmake
vendored
6
firmware/application/external/external.cmake
vendored
@ -126,7 +126,10 @@ set(EXTCPPSRC
|
|||||||
#flippertx
|
#flippertx
|
||||||
external/flippertx/main.cpp
|
external/flippertx/main.cpp
|
||||||
external/flippertx/ui_flippertx.cpp
|
external/flippertx/ui_flippertx.cpp
|
||||||
|
|
||||||
|
#remote
|
||||||
|
external/remote/main.cpp
|
||||||
|
external/remote/ui_remote.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(EXTAPPLIST
|
set(EXTAPPLIST
|
||||||
@ -160,4 +163,5 @@ set(EXTAPPLIST
|
|||||||
ook_editor
|
ook_editor
|
||||||
shoppingcart_lock
|
shoppingcart_lock
|
||||||
flippertx
|
flippertx
|
||||||
|
remote
|
||||||
)
|
)
|
||||||
|
6
firmware/application/external/external.ld
vendored
6
firmware/application/external/external.ld
vendored
@ -53,6 +53,7 @@ MEMORY
|
|||||||
ram_external_app_ookbrute(rwx) : org = 0xADCC0000, len = 32k
|
ram_external_app_ookbrute(rwx) : org = 0xADCC0000, len = 32k
|
||||||
ram_external_app_flippertx(rwx) : org = 0xADCD0000, len = 32k
|
ram_external_app_flippertx(rwx) : org = 0xADCD0000, len = 32k
|
||||||
ram_external_app_ook_editor(rwx) : org = 0xADCE0000, len = 32k
|
ram_external_app_ook_editor(rwx) : org = 0xADCE0000, len = 32k
|
||||||
|
ram_external_app_remote(rwx) : org = 0xADCF0000, len = 32k
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
@ -238,4 +239,9 @@ SECTIONS
|
|||||||
*(*ui*external_app*flippertx*);
|
*(*ui*external_app*flippertx*);
|
||||||
} > ram_external_app_flippertx
|
} > ram_external_app_flippertx
|
||||||
|
|
||||||
|
.external_app_remote : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.external_app.app_remote.application_information));
|
||||||
|
*(*ui*external_app*remote*);
|
||||||
|
} > ram_external_app_remote
|
||||||
}
|
}
|
||||||
|
82
firmware/application/external/remote/main.cpp
vendored
Normal file
82
firmware/application/external/remote/main.cpp
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 gullradriel
|
||||||
|
*
|
||||||
|
* 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_remote.hpp"
|
||||||
|
#include "ui_navigation.hpp"
|
||||||
|
#include "external_app.hpp"
|
||||||
|
|
||||||
|
namespace ui::external_app::remote {
|
||||||
|
void initialize_app(ui::NavigationView& nav) {
|
||||||
|
nav.push<RemoteAppView>();
|
||||||
|
}
|
||||||
|
} // namespace ui::external_app::remote
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
__attribute__((section(".external_app.app_remote.application_information"), used)) application_information_t _application_information_remote = {
|
||||||
|
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||||
|
/*.externalAppEntry = */ ui::external_app::remote::initialize_app,
|
||||||
|
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||||
|
/*.app_version = */ VERSION_MD5,
|
||||||
|
|
||||||
|
/*.app_name = */ "Remote",
|
||||||
|
/*.bitmap_data = */ {
|
||||||
|
0x20,
|
||||||
|
0x00,
|
||||||
|
0x20,
|
||||||
|
0x00,
|
||||||
|
0x20,
|
||||||
|
0x00,
|
||||||
|
0x20,
|
||||||
|
0x00,
|
||||||
|
0xE0,
|
||||||
|
0x07,
|
||||||
|
0xF0,
|
||||||
|
0x0F,
|
||||||
|
0x30,
|
||||||
|
0x0C,
|
||||||
|
0x30,
|
||||||
|
0x0C,
|
||||||
|
0xF0,
|
||||||
|
0x0F,
|
||||||
|
0xF0,
|
||||||
|
0x0F,
|
||||||
|
0x70,
|
||||||
|
0x0D,
|
||||||
|
0xB0,
|
||||||
|
0x0E,
|
||||||
|
0x70,
|
||||||
|
0x0D,
|
||||||
|
0xB0,
|
||||||
|
0x0E,
|
||||||
|
0xF0,
|
||||||
|
0x0F,
|
||||||
|
0xE0,
|
||||||
|
0x07,
|
||||||
|
},
|
||||||
|
/*.icon_color = */ ui::Color::green().v,
|
||||||
|
/*.menu_location = */ app_location_t::HOME,
|
||||||
|
|
||||||
|
/*.m4_app_tag = portapack::spi_flash::image_tag_replay */ {'P', 'R', 'E', 'P'},
|
||||||
|
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||||
|
};
|
||||||
|
}
|
@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ui_remote.hpp"
|
#include "ui_remote.hpp"
|
||||||
|
|
||||||
#include "binder.hpp"
|
#include "binder.hpp"
|
||||||
#include "convert.hpp"
|
#include "convert.hpp"
|
||||||
#include "file_reader.hpp"
|
#include "file_reader.hpp"
|
||||||
@ -34,11 +33,11 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "file_path.hpp"
|
#include "file_path.hpp"
|
||||||
|
|
||||||
|
namespace ui::external_app::remote {
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace ui {
|
|
||||||
|
|
||||||
static constexpr uint8_t text_edit_max = 30;
|
static constexpr uint8_t text_edit_max = 30;
|
||||||
|
|
||||||
/* RemoteEntryModel **************************************/
|
/* RemoteEntryModel **************************************/
|
||||||
@ -309,9 +308,9 @@ void RemoteEntryEditView::load_path(std::filesystem::path&& path) {
|
|||||||
entry_.metadata = {transmitter_model.target_frequency(), 500'000};
|
entry_.metadata = {transmitter_model.target_frequency(), 500'000};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RemoteView ********************************************/
|
/* RemoteAppView ********************************************/
|
||||||
|
|
||||||
RemoteView::RemoteView(
|
RemoteAppView::RemoteAppView(
|
||||||
NavigationView& nav)
|
NavigationView& nav)
|
||||||
: nav_{nav} {
|
: nav_{nav} {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
||||||
@ -365,27 +364,27 @@ RemoteView::RemoteView(
|
|||||||
refresh_ui();
|
refresh_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteView::RemoteView(NavigationView& nav, fs::path path)
|
RemoteAppView::RemoteAppView(NavigationView& nav, fs::path path)
|
||||||
: RemoteView(nav) {
|
: RemoteAppView(nav) {
|
||||||
load_remote(std::move(path));
|
load_remote(std::move(path));
|
||||||
refresh_ui();
|
refresh_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteView::~RemoteView() {
|
RemoteAppView::~RemoteAppView() {
|
||||||
stop();
|
stop();
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
|
|
||||||
save_remote(/*show_error*/ false);
|
save_remote(/*show_error*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::focus() {
|
void RemoteAppView::focus() {
|
||||||
if (model_.entries.empty())
|
if (model_.entries.empty())
|
||||||
button_add.focus();
|
button_add.focus();
|
||||||
else
|
else
|
||||||
buttons_[0]->focus();
|
buttons_[0]->focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::create_buttons() {
|
void RemoteAppView::create_buttons() {
|
||||||
// Handler callbacks.
|
// Handler callbacks.
|
||||||
auto handle_send = [this](RemoteButton& btn) {
|
auto handle_send = [this](RemoteButton& btn) {
|
||||||
if (btn.entry()->path.empty())
|
if (btn.entry()->path.empty())
|
||||||
@ -420,7 +419,7 @@ void RemoteView::create_buttons() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::reset_buttons() {
|
void RemoteAppView::reset_buttons() {
|
||||||
// Whever the model's entries instance is invalidated,
|
// Whever the model's entries instance is invalidated,
|
||||||
// all the pointers in the buttons will end up dangling.
|
// all the pointers in the buttons will end up dangling.
|
||||||
// TODO: This is pretty lame. Could maybe static alloc?
|
// TODO: This is pretty lame. Could maybe static alloc?
|
||||||
@ -428,7 +427,7 @@ void RemoteView::reset_buttons() {
|
|||||||
btn->set_entry(nullptr);
|
btn->set_entry(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::refresh_ui() {
|
void RemoteAppView::refresh_ui() {
|
||||||
field_title.set_text(model_.name);
|
field_title.set_text(model_.name);
|
||||||
field_filename.set_text(remote_path_.stem().string());
|
field_filename.set_text(remote_path_.stem().string());
|
||||||
|
|
||||||
@ -441,7 +440,7 @@ void RemoteView::refresh_ui() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::add_button() {
|
void RemoteAppView::add_button() {
|
||||||
if (model_.entries.size() >= max_buttons)
|
if (model_.entries.size() >= max_buttons)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -454,7 +453,7 @@ void RemoteView::add_button() {
|
|||||||
set_needs_save();
|
set_needs_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::edit_button(RemoteButton& btn) {
|
void RemoteAppView::edit_button(RemoteButton& btn) {
|
||||||
// Don't let replay thread read the model while editing.
|
// Don't let replay thread read the model while editing.
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
@ -471,7 +470,7 @@ void RemoteView::edit_button(RemoteButton& btn) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::send_button(RemoteButton& btn) {
|
void RemoteAppView::send_button(RemoteButton& btn) {
|
||||||
// TODO: If this is called while is_sending() == true,
|
// TODO: If this is called while is_sending() == true,
|
||||||
// it just stops and doesn't start the new button?
|
// it just stops and doesn't start the new button?
|
||||||
|
|
||||||
@ -510,14 +509,14 @@ void RemoteView::send_button(RemoteButton& btn) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::stop() {
|
void RemoteAppView::stop() {
|
||||||
// This terminates the underlying chThread.
|
// This terminates the underlying chThread.
|
||||||
replay_thread_.reset();
|
replay_thread_.reset();
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
ready_signal_ = false;
|
ready_signal_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::new_remote() {
|
void RemoteAppView::new_remote() {
|
||||||
save_remote();
|
save_remote();
|
||||||
init_remote();
|
init_remote();
|
||||||
refresh_ui();
|
refresh_ui();
|
||||||
@ -526,7 +525,7 @@ void RemoteView::new_remote() {
|
|||||||
set_dirty();
|
set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::open_remote() {
|
void RemoteAppView::open_remote() {
|
||||||
auto open_view = nav_.push<FileLoadView>(".REM");
|
auto open_view = nav_.push<FileLoadView>(".REM");
|
||||||
open_view->push_dir(remotes_dir);
|
open_view->push_dir(remotes_dir);
|
||||||
open_view->on_changed = [this](fs::path path) {
|
open_view->on_changed = [this](fs::path path) {
|
||||||
@ -536,7 +535,7 @@ void RemoteView::open_remote() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::init_remote() {
|
void RemoteAppView::init_remote() {
|
||||||
model_ = {"<Unnamed Remote>", {}};
|
model_ = {"<Unnamed Remote>", {}};
|
||||||
reset_buttons();
|
reset_buttons();
|
||||||
set_remote_path(next_filename_matching_pattern(remotes_dir / u"REMOTE_????.REM"));
|
set_remote_path(next_filename_matching_pattern(remotes_dir / u"REMOTE_????.REM"));
|
||||||
@ -546,14 +545,14 @@ void RemoteView::init_remote() {
|
|||||||
show_error("Couldn't make new remote file.");
|
show_error("Couldn't make new remote file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RemoteView::load_remote(fs::path&& path) {
|
bool RemoteAppView::load_remote(fs::path&& path) {
|
||||||
set_remote_path(std::move(path));
|
set_remote_path(std::move(path));
|
||||||
set_needs_save(false);
|
set_needs_save(false);
|
||||||
reset_buttons();
|
reset_buttons();
|
||||||
return model_.load(remote_path_);
|
return model_.load(remote_path_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::save_remote(bool show_errors) {
|
void RemoteAppView::save_remote(bool show_errors) {
|
||||||
if (!needs_save_)
|
if (!needs_save_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -564,7 +563,7 @@ void RemoteView::save_remote(bool show_errors) {
|
|||||||
set_needs_save(false);
|
set_needs_save(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::rename_remote(const std::string& new_name) {
|
void RemoteAppView::rename_remote(const std::string& new_name) {
|
||||||
auto folder = remote_path_.parent_path();
|
auto folder = remote_path_.parent_path();
|
||||||
auto ext = remote_path_.extension();
|
auto ext = remote_path_.extension();
|
||||||
auto new_path = folder / new_name + ext;
|
auto new_path = folder / new_name + ext;
|
||||||
@ -581,7 +580,7 @@ void RemoteView::rename_remote(const std::string& new_name) {
|
|||||||
set_remote_path(std::move(new_path));
|
set_remote_path(std::move(new_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::handle_replay_thread_done(uint32_t return_code) {
|
void RemoteAppView::handle_replay_thread_done(uint32_t return_code) {
|
||||||
if (return_code == ReplayThread::END_OF_FILE) {
|
if (return_code == ReplayThread::END_OF_FILE) {
|
||||||
if (check_loop.value() && current_btn_) {
|
if (check_loop.value() && current_btn_) {
|
||||||
send_button(*current_btn_);
|
send_button(*current_btn_);
|
||||||
@ -598,15 +597,15 @@ void RemoteView::handle_replay_thread_done(uint32_t return_code) {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::set_remote_path(fs::path&& path) {
|
void RemoteAppView::set_remote_path(fs::path&& path) {
|
||||||
// Unfortunately, have to keep these two in sync because
|
// Unfortunately, have to keep these two in sync because
|
||||||
// settings doesn't know about fs::path.
|
// settings doesn't know about fs::path.
|
||||||
remote_path_ = std::move(path);
|
remote_path_ = std::move(path);
|
||||||
settings_.remote_path = remote_path_.string();
|
settings_.remote_path = remote_path_.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteView::show_error(const std::string& msg) const {
|
void RemoteAppView::show_error(const std::string& msg) const {
|
||||||
nav_.display_modal("Error", msg);
|
nav_.display_modal("Error", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} // namespace ui::external_app::remote
|
@ -41,7 +41,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ui {
|
namespace ui::external_app::remote {
|
||||||
|
|
||||||
/* Maps icon index to bitmap. */
|
/* Maps icon index to bitmap. */
|
||||||
class RemoteIcons {
|
class RemoteIcons {
|
||||||
@ -257,14 +257,14 @@ class RemoteEntryEditView : public View {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* App that allows for buttons to be bound to captures for playback. */
|
/* App that allows for buttons to be bound to captures for playback. */
|
||||||
class RemoteView : public View {
|
class RemoteAppView : public View {
|
||||||
public:
|
public:
|
||||||
RemoteView(NavigationView& nav);
|
RemoteAppView(NavigationView& nav);
|
||||||
RemoteView(NavigationView& nav, std::filesystem::path path);
|
RemoteAppView(NavigationView& nav, std::filesystem::path path);
|
||||||
~RemoteView();
|
~RemoteAppView();
|
||||||
|
|
||||||
RemoteView(const RemoteView&) = delete;
|
RemoteAppView(const RemoteAppView&) = delete;
|
||||||
RemoteView& operator=(const RemoteView&) = delete;
|
RemoteAppView& operator=(const RemoteAppView&) = delete;
|
||||||
|
|
||||||
std::string title() const override { return "Remote"; };
|
std::string title() const override { return "Remote"; };
|
||||||
void focus() override;
|
void focus() override;
|
||||||
@ -385,4 +385,4 @@ class RemoteView : public View {
|
|||||||
}};
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} // namespace ui::external_app::remote
|
@ -52,7 +52,6 @@
|
|||||||
#include "ui_pocsag_tx.hpp"
|
#include "ui_pocsag_tx.hpp"
|
||||||
#include "ui_rds.hpp"
|
#include "ui_rds.hpp"
|
||||||
#include "ui_recon.hpp"
|
#include "ui_recon.hpp"
|
||||||
#include "ui_remote.hpp"
|
|
||||||
#include "ui_scanner.hpp"
|
#include "ui_scanner.hpp"
|
||||||
#include "ui_sd_over_usb.hpp"
|
#include "ui_sd_over_usb.hpp"
|
||||||
#include "ui_sd_wipe.hpp"
|
#include "ui_sd_wipe.hpp"
|
||||||
@ -126,7 +125,6 @@ const NavigationView::AppList NavigationView::appList = {
|
|||||||
{nullptr, "Transmit", HOME, Color::cyan(), &bitmap_icon_transmit, new ViewFactory<TransmittersMenuView>()},
|
{nullptr, "Transmit", HOME, Color::cyan(), &bitmap_icon_transmit, new ViewFactory<TransmittersMenuView>()},
|
||||||
{"capture", "Capture", HOME, Color::red(), &bitmap_icon_capture, new ViewFactory<CaptureAppView>()},
|
{"capture", "Capture", HOME, Color::red(), &bitmap_icon_capture, new ViewFactory<CaptureAppView>()},
|
||||||
{"replay", "Replay", HOME, Color::green(), &bitmap_icon_replay, new ViewFactory<PlaylistView>()},
|
{"replay", "Replay", HOME, Color::green(), &bitmap_icon_replay, new ViewFactory<PlaylistView>()},
|
||||||
{"remote", "Remote", HOME, ui::Color::green(), &bitmap_icon_remote, new ViewFactory<RemoteView>()},
|
|
||||||
{"scanner", "Scanner", HOME, Color::green(), &bitmap_icon_scanner, new ViewFactory<ScannerView>()},
|
{"scanner", "Scanner", HOME, Color::green(), &bitmap_icon_scanner, new ViewFactory<ScannerView>()},
|
||||||
{"microphone", "Microphone", HOME, Color::green(), &bitmap_icon_microphone, new ViewFactory<MicTXView>()},
|
{"microphone", "Microphone", HOME, Color::green(), &bitmap_icon_microphone, new ViewFactory<MicTXView>()},
|
||||||
{"lookingglass", "Looking Glass", HOME, Color::green(), &bitmap_icon_looking, new ViewFactory<GlassView>()},
|
{"lookingglass", "Looking Glass", HOME, Color::green(), &bitmap_icon_looking, new ViewFactory<GlassView>()},
|
||||||
@ -851,6 +849,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_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_); }});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user