mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-04 15:35:32 +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_recon_settings.cpp
|
||||
apps/ui_recon.cpp
|
||||
apps/ui_remote.cpp
|
||||
apps/ui_scanner.cpp
|
||||
apps/ui_sd_over_usb.cpp
|
||||
apps/ui_sd_wipe.cpp
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <algorithm>
|
||||
#include "ui_fileman.hpp"
|
||||
#include "ui_playlist.hpp"
|
||||
#include "ui_remote.hpp"
|
||||
#include "ui_ss_viewer.hpp"
|
||||
#include "ui_bmp_file_viewer.hpp"
|
||||
#include "ui_text_editor.hpp"
|
||||
@ -704,10 +703,11 @@ bool FileManagerView::handle_file_open() {
|
||||
|
||||
reload_current(false);
|
||||
return true;
|
||||
} else if (path_iequal(rem_ext, ext)) {
|
||||
}
|
||||
/*else if (path_iequal(rem_ext, ext)) {
|
||||
nav_.push<RemoteView>(path);
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
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
|
||||
external/flippertx/main.cpp
|
||||
external/flippertx/ui_flippertx.cpp
|
||||
|
||||
|
||||
#remote
|
||||
external/remote/main.cpp
|
||||
external/remote/ui_remote.cpp
|
||||
)
|
||||
|
||||
set(EXTAPPLIST
|
||||
@ -160,4 +163,5 @@ set(EXTAPPLIST
|
||||
ook_editor
|
||||
shoppingcart_lock
|
||||
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_flippertx(rwx) : org = 0xADCD0000, len = 32k
|
||||
ram_external_app_ook_editor(rwx) : org = 0xADCE0000, len = 32k
|
||||
ram_external_app_remote(rwx) : org = 0xADCF0000, len = 32k
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@ -238,4 +239,9 @@ SECTIONS
|
||||
*(*ui*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 "binder.hpp"
|
||||
#include "convert.hpp"
|
||||
#include "file_reader.hpp"
|
||||
@ -34,11 +33,11 @@
|
||||
#include "utility.hpp"
|
||||
#include "file_path.hpp"
|
||||
|
||||
namespace ui::external_app::remote {
|
||||
|
||||
using namespace portapack;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace ui {
|
||||
|
||||
static constexpr uint8_t text_edit_max = 30;
|
||||
|
||||
/* RemoteEntryModel **************************************/
|
||||
@ -309,9 +308,9 @@ void RemoteEntryEditView::load_path(std::filesystem::path&& path) {
|
||||
entry_.metadata = {transmitter_model.target_frequency(), 500'000};
|
||||
}
|
||||
|
||||
/* RemoteView ********************************************/
|
||||
/* RemoteAppView ********************************************/
|
||||
|
||||
RemoteView::RemoteView(
|
||||
RemoteAppView::RemoteAppView(
|
||||
NavigationView& nav)
|
||||
: nav_{nav} {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
||||
@ -365,27 +364,27 @@ RemoteView::RemoteView(
|
||||
refresh_ui();
|
||||
}
|
||||
|
||||
RemoteView::RemoteView(NavigationView& nav, fs::path path)
|
||||
: RemoteView(nav) {
|
||||
RemoteAppView::RemoteAppView(NavigationView& nav, fs::path path)
|
||||
: RemoteAppView(nav) {
|
||||
load_remote(std::move(path));
|
||||
refresh_ui();
|
||||
}
|
||||
|
||||
RemoteView::~RemoteView() {
|
||||
RemoteAppView::~RemoteAppView() {
|
||||
stop();
|
||||
baseband::shutdown();
|
||||
|
||||
save_remote(/*show_error*/ false);
|
||||
}
|
||||
|
||||
void RemoteView::focus() {
|
||||
void RemoteAppView::focus() {
|
||||
if (model_.entries.empty())
|
||||
button_add.focus();
|
||||
else
|
||||
buttons_[0]->focus();
|
||||
}
|
||||
|
||||
void RemoteView::create_buttons() {
|
||||
void RemoteAppView::create_buttons() {
|
||||
// Handler callbacks.
|
||||
auto handle_send = [this](RemoteButton& btn) {
|
||||
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,
|
||||
// all the pointers in the buttons will end up dangling.
|
||||
// TODO: This is pretty lame. Could maybe static alloc?
|
||||
@ -428,7 +427,7 @@ void RemoteView::reset_buttons() {
|
||||
btn->set_entry(nullptr);
|
||||
}
|
||||
|
||||
void RemoteView::refresh_ui() {
|
||||
void RemoteAppView::refresh_ui() {
|
||||
field_title.set_text(model_.name);
|
||||
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)
|
||||
return;
|
||||
|
||||
@ -454,7 +453,7 @@ void RemoteView::add_button() {
|
||||
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.
|
||||
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,
|
||||
// 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.
|
||||
replay_thread_.reset();
|
||||
transmitter_model.disable();
|
||||
ready_signal_ = false;
|
||||
}
|
||||
|
||||
void RemoteView::new_remote() {
|
||||
void RemoteAppView::new_remote() {
|
||||
save_remote();
|
||||
init_remote();
|
||||
refresh_ui();
|
||||
@ -526,7 +525,7 @@ void RemoteView::new_remote() {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void RemoteView::open_remote() {
|
||||
void RemoteAppView::open_remote() {
|
||||
auto open_view = nav_.push<FileLoadView>(".REM");
|
||||
open_view->push_dir(remotes_dir);
|
||||
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>", {}};
|
||||
reset_buttons();
|
||||
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.");
|
||||
}
|
||||
|
||||
bool RemoteView::load_remote(fs::path&& path) {
|
||||
bool RemoteAppView::load_remote(fs::path&& path) {
|
||||
set_remote_path(std::move(path));
|
||||
set_needs_save(false);
|
||||
reset_buttons();
|
||||
return model_.load(remote_path_);
|
||||
}
|
||||
|
||||
void RemoteView::save_remote(bool show_errors) {
|
||||
void RemoteAppView::save_remote(bool show_errors) {
|
||||
if (!needs_save_)
|
||||
return;
|
||||
|
||||
@ -564,7 +563,7 @@ void RemoteView::save_remote(bool show_errors) {
|
||||
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 ext = remote_path_.extension();
|
||||
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));
|
||||
}
|
||||
|
||||
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 (check_loop.value() && current_btn_) {
|
||||
send_button(*current_btn_);
|
||||
@ -598,15 +597,15 @@ void RemoteView::handle_replay_thread_done(uint32_t return_code) {
|
||||
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
|
||||
// settings doesn't know about fs::path.
|
||||
remote_path_ = std::move(path);
|
||||
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);
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
} // namespace ui::external_app::remote
|
@ -41,7 +41,7 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::remote {
|
||||
|
||||
/* Maps icon index to bitmap. */
|
||||
class RemoteIcons {
|
||||
@ -257,14 +257,14 @@ class RemoteEntryEditView : public View {
|
||||
};
|
||||
|
||||
/* App that allows for buttons to be bound to captures for playback. */
|
||||
class RemoteView : public View {
|
||||
class RemoteAppView : public View {
|
||||
public:
|
||||
RemoteView(NavigationView& nav);
|
||||
RemoteView(NavigationView& nav, std::filesystem::path path);
|
||||
~RemoteView();
|
||||
RemoteAppView(NavigationView& nav);
|
||||
RemoteAppView(NavigationView& nav, std::filesystem::path path);
|
||||
~RemoteAppView();
|
||||
|
||||
RemoteView(const RemoteView&) = delete;
|
||||
RemoteView& operator=(const RemoteView&) = delete;
|
||||
RemoteAppView(const RemoteAppView&) = delete;
|
||||
RemoteAppView& operator=(const RemoteAppView&) = delete;
|
||||
|
||||
std::string title() const override { return "Remote"; };
|
||||
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_rds.hpp"
|
||||
#include "ui_recon.hpp"
|
||||
#include "ui_remote.hpp"
|
||||
#include "ui_scanner.hpp"
|
||||
#include "ui_sd_over_usb.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>()},
|
||||
{"capture", "Capture", HOME, Color::red(), &bitmap_icon_capture, new ViewFactory<CaptureAppView>()},
|
||||
{"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>()},
|
||||
{"microphone", "Microphone", HOME, Color::green(), &bitmap_icon_microphone, new ViewFactory<MicTXView>()},
|
||||
{"lookingglass", "Looking Glass", HOME, Color::green(), &bitmap_icon_looking, new ViewFactory<GlassView>()},
|
||||
@ -851,6 +849,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav)
|
||||
|
||||
void SystemMenuView::on_populate() {
|
||||
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_); }});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user