mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-22 15:39:04 +00:00
Random splash on boot (#2961)
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
#include "ui_touch_calibration.hpp"
|
||||
#include "ui_text_editor.hpp"
|
||||
#include "ui_external_items_menu_loader.hpp"
|
||||
#include "ui_ss_viewer.hpp"
|
||||
#include "ui_fileman.hpp"
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
@@ -348,7 +350,6 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
add_children({&checkbox_disable_touchscreen,
|
||||
&checkbox_bloff,
|
||||
&options_bloff,
|
||||
&checkbox_showsplash,
|
||||
&checkbox_showclock,
|
||||
&options_clockformat,
|
||||
&checkbox_guireturnflag,
|
||||
@@ -375,7 +376,6 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
}
|
||||
|
||||
checkbox_disable_touchscreen.set_value(pmem::disable_touchscreen());
|
||||
checkbox_showsplash.set_value(pmem::config_splash());
|
||||
checkbox_showclock.set_value(!pmem::hide_clock());
|
||||
checkbox_guireturnflag.set_value(pmem::show_gui_return_icon());
|
||||
|
||||
@@ -414,7 +414,6 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
pmem::set_clock_with_date(false);
|
||||
}
|
||||
|
||||
pmem::set_config_splash(checkbox_showsplash.value());
|
||||
pmem::set_clock_hidden(!checkbox_showclock.value());
|
||||
pmem::set_gui_return_icon(checkbox_guireturnflag.value());
|
||||
pmem::set_disable_touchscreen(checkbox_disable_touchscreen.value());
|
||||
@@ -1113,6 +1112,46 @@ void SetBatteryView::focus() {
|
||||
button_cancel.focus();
|
||||
}
|
||||
|
||||
/* SetSlpash *********************************************/
|
||||
|
||||
SetSplash::SetSplash(NavigationView& nav) {
|
||||
add_children({&checkbox_showsplash,
|
||||
&checkbox_randomsplash,
|
||||
&message,
|
||||
&button_picture_select,
|
||||
&button_save,
|
||||
&button_cancel});
|
||||
|
||||
checkbox_showsplash.set_value(pmem::config_splash());
|
||||
splash_bmp_exists = file_exists(splash_dot_bmp);
|
||||
checkbox_randomsplash.set_value(!splash_bmp_exists);
|
||||
message.hidden(splash_bmp_exists);
|
||||
|
||||
checkbox_randomsplash.on_select = [this](Checkbox&, bool v) {
|
||||
random_enabled = v;
|
||||
};
|
||||
|
||||
button_picture_select.on_select = [this, &nav](Button&) {
|
||||
auto ret = nav.push<FileManagerView>();
|
||||
ret->push_dir(splash_dir);
|
||||
};
|
||||
|
||||
button_save.on_select = [&nav, this](Button&) {
|
||||
if (random_enabled == true) delete_file(splash_dot_bmp);
|
||||
pmem::set_config_splash(checkbox_showsplash.value());
|
||||
send_system_refresh();
|
||||
nav.pop();
|
||||
};
|
||||
|
||||
button_cancel.on_select = [&nav, this](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
void SetSplash::focus() {
|
||||
button_save.focus();
|
||||
}
|
||||
|
||||
/* SettingsMenuView **************************************/
|
||||
|
||||
SettingsMenuView::SettingsMenuView(NavigationView& nav)
|
||||
@@ -1146,6 +1185,7 @@ void SettingsMenuView::on_populate() {
|
||||
{"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>(); }},
|
||||
{"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetThemeView>(); }},
|
||||
{"Splash settings", ui::Color::dark_cyan(), &bitmap_icon_file_image, [this]() { nav_.push<SetSplash>(); }},
|
||||
});
|
||||
|
||||
if (battery::BatteryManagement::isDetected()) add_item({"Battery", ui::Color::dark_cyan(), &bitmap_icon_batt_icon, [this]() { nav_.push<SetBatteryView>(); }});
|
||||
|
||||
@@ -343,77 +343,72 @@ class SetUIView : public View {
|
||||
{"1 hour", backlight_timeout_t::Timeout3600Sec},
|
||||
}};
|
||||
|
||||
Checkbox checkbox_showsplash{
|
||||
{3 * 8, 6 * 16},
|
||||
20,
|
||||
"Show splash"};
|
||||
|
||||
Checkbox checkbox_showclock{
|
||||
{3 * 8, 8 * 16},
|
||||
{3 * 8, 6 * 16},
|
||||
20,
|
||||
"Show clock with:"};
|
||||
|
||||
OptionsField options_clockformat{
|
||||
{60, 9 * 16 + 8},
|
||||
{60, 7 * 16 + 8},
|
||||
20,
|
||||
{{"time only", 0},
|
||||
{"time and date", 1}}};
|
||||
|
||||
Checkbox checkbox_guireturnflag{
|
||||
{3 * 8, 11 * 16},
|
||||
{3 * 8, 9 * 16},
|
||||
20,
|
||||
"Back button in menu"};
|
||||
|
||||
Labels labels{
|
||||
{{3 * 8, 13 * 16}, "Show/Hide Status Icons", Theme::getInstance()->fg_light->foreground},
|
||||
{{3 * 8, 11 * 16}, "Show/Hide Status Icons", Theme::getInstance()->fg_light->foreground},
|
||||
};
|
||||
|
||||
ImageToggle toggle_camera{
|
||||
{2 * 8, 14 * 16 + 2, 16, 16},
|
||||
{2 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_camera};
|
||||
|
||||
ImageToggle toggle_sleep{
|
||||
{4 * 8, 14 * 16 + 2, 16, 16},
|
||||
{4 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_sleep};
|
||||
|
||||
ImageToggle toggle_stealth{
|
||||
{6 * 8, 14 * 16 + 2, 16, 16},
|
||||
{6 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_stealth};
|
||||
|
||||
ImageToggle toggle_converter{
|
||||
{8 * 8, 14 * 16 + 2, 16, 16},
|
||||
{8 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_upconvert};
|
||||
|
||||
ImageToggle toggle_bias_tee{
|
||||
{10 * 8, 14 * 16 + 2, 16, 16},
|
||||
{10 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_biast_off};
|
||||
|
||||
ImageToggle toggle_clock{
|
||||
{12 * 8, 14 * 16 + 2, 8, 16},
|
||||
{12 * 8, 12 * 16 + 2, 8, 16},
|
||||
&bitmap_icon_clk_ext};
|
||||
|
||||
ImageToggle toggle_mute{
|
||||
{13 * 8, 14 * 16 + 2, 16, 16},
|
||||
{13 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_speaker_and_headphones_mute};
|
||||
|
||||
ImageToggle toggle_speaker{
|
||||
{15 * 8, 14 * 16 + 2, 16, 16},
|
||||
{15 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_speaker_mute};
|
||||
|
||||
ImageToggle toggle_battery_icon{
|
||||
{17 * 8, 14 * 16 + 2, 16, 16},
|
||||
{17 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_batt_icon};
|
||||
|
||||
ImageToggle toggle_battery_text{
|
||||
{19 * 8, 14 * 16 + 2, 16, 16},
|
||||
{19 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_batt_text};
|
||||
|
||||
ImageToggle toggle_fake_brightness{
|
||||
{21 * 8, 14 * 16 + 2, 16, 16},
|
||||
{21 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_icon_brightness};
|
||||
|
||||
ImageToggle toggle_sd_card{
|
||||
{23 * 8, 14 * 16 + 2, 16, 16},
|
||||
{23 * 8, 12 * 16 + 2, 16, 16},
|
||||
&bitmap_sd_card_ok};
|
||||
|
||||
Button button_save{
|
||||
@@ -1069,6 +1064,43 @@ class SettingsMenuView : public BtnGridView {
|
||||
void on_populate() override;
|
||||
};
|
||||
|
||||
class SetSplash : public View {
|
||||
public:
|
||||
SetSplash(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Splash"; };
|
||||
|
||||
private:
|
||||
bool splash_bmp_exists = false;
|
||||
bool random_enabled = false;
|
||||
|
||||
Checkbox checkbox_showsplash{
|
||||
{3 * 8, 1 * 16},
|
||||
20,
|
||||
"Show splash"};
|
||||
|
||||
Checkbox checkbox_randomsplash{
|
||||
{3 * 8, 3 * 16},
|
||||
20,
|
||||
"Random splash on boot"};
|
||||
|
||||
Text message{{UI_POS_X(1), UI_POS_Y(6), UI_POS_WIDTH(26), UI_POS_HEIGHT(1)}, "Pick image to stop random."};
|
||||
|
||||
Button button_picture_select{
|
||||
{UI_POS_X_CENTER(8) - UI_POS_WIDTH(4), UI_POS_Y_BOTTOM(7), UI_POS_WIDTH(13), UI_POS_HEIGHT(2)},
|
||||
"Select pict."};
|
||||
|
||||
Button button_save{
|
||||
{UI_POS_X_CENTER(12) - UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), UI_POS_WIDTH(12), UI_POS_HEIGHT(2)},
|
||||
"Save"};
|
||||
|
||||
Button button_cancel{
|
||||
{UI_POS_X_CENTER(16) + UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), UI_POS_WIDTH(12), UI_POS_HEIGHT(2)},
|
||||
"Cancel"};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
#endif /*__UI_SETTINGS_H__*/
|
||||
|
||||
@@ -27,8 +27,6 @@ namespace fs = std::filesystem;
|
||||
|
||||
namespace ui {
|
||||
|
||||
const std::filesystem::path splash_dot_bmp{u"/splash.bmp"};
|
||||
|
||||
ScreenshotViewer::ScreenshotViewer(
|
||||
NavigationView& nav,
|
||||
const std::filesystem::path& path)
|
||||
@@ -44,7 +42,6 @@ bool ScreenshotViewer::on_key(KeyEvent) {
|
||||
|
||||
void ScreenshotViewer::paint(Painter& painter) {
|
||||
File file{};
|
||||
|
||||
painter.fill_rectangle({0, 0, screen_width, screen_height}, Color::black());
|
||||
|
||||
auto show_invalid = [&]() {
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "file.hpp"
|
||||
#include "file_path.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
extern const std::filesystem::path splash_dot_bmp;
|
||||
|
||||
class ScreenshotViewer : public View {
|
||||
public:
|
||||
ScreenshotViewer(NavigationView& nav, const std::filesystem::path& path);
|
||||
@@ -49,7 +48,6 @@ class SplashViewer : public View {
|
||||
SplashViewer(NavigationView& nav, const std::filesystem::path& path);
|
||||
bool on_key(KeyEvent key) override;
|
||||
void paint(Painter& painter) override;
|
||||
void update_ss(void);
|
||||
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
|
||||
@@ -53,5 +53,6 @@ const std::filesystem::path hopper_dir = u"HOPPER";
|
||||
const std::filesystem::path subghz_dir = u"SUBGHZ";
|
||||
const std::filesystem::path waterfalls_dir = u"WATERFALLS";
|
||||
const std::filesystem::path macaddress_dir = u"MACADDRESS";
|
||||
const std::filesystem::path splash_dot_bmp = u"/splash.bmp";
|
||||
const std::filesystem::path keeloq_keys_dir = u"KEELOQKEYS";
|
||||
const std::filesystem::path keeloq_remotes_dir = u"KEELOQREMOTES";
|
||||
|
||||
@@ -58,4 +58,6 @@ extern const std::filesystem::path macaddress_dir;
|
||||
extern const std::filesystem::path keeloq_keys_dir;
|
||||
extern const std::filesystem::path keeloq_remotes_dir;
|
||||
|
||||
extern const std::filesystem::path splash_dot_bmp;
|
||||
|
||||
#endif /* __FILE_PATH_H__ */
|
||||
|
||||
@@ -1054,17 +1054,66 @@ SplashScreenView::SplashScreenView(NavigationView& nav)
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t SplashScreenView::myrand(uint32_t* state) {
|
||||
uint32_t x = *state;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
*state = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void SplashScreenView::get_random_splash_file(std::filesystem::path& path) {
|
||||
path = u"";
|
||||
|
||||
uint32_t rng_state = LPC_RTC->CTIME0;
|
||||
if (rng_state == 0) rng_state = 0xABBACAFE;
|
||||
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
int32_t valid_count = 0;
|
||||
|
||||
// Open directory
|
||||
if (f_opendir(&dir, (const TCHAR*)splash_dir.c_str()) == FR_OK) {
|
||||
while (f_readdir(&dir, &fno) == FR_OK && fno.fname[0] != 0) {
|
||||
// Skip directories
|
||||
if (fno.fattrib & AM_DIR) continue;
|
||||
int len = 0;
|
||||
while (fno.fname[len]) len++; // Get length
|
||||
if (len >= 4) {
|
||||
const TCHAR* ext = &fno.fname[len - 4];
|
||||
// Check extension case-insensitively
|
||||
if (ext[0] == '.' &&
|
||||
(ext[1] == 'B' || ext[1] == 'b') &&
|
||||
(ext[2] == 'M' || ext[2] == 'm') &&
|
||||
(ext[3] == 'P' || ext[3] == 'p')) {
|
||||
valid_count++;
|
||||
// Reservoir Sampling:
|
||||
if ((myrand(&rng_state) % valid_count) == 0) {
|
||||
path = splash_dir / fno.fname;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
}
|
||||
|
||||
void SplashScreenView::paint(Painter&) {
|
||||
constexpr const uint8_t zoom = 3;
|
||||
set_clean();
|
||||
// if (!bmp_view.load_bmp(splash_dot_bmp)) { //--too slow drawing, bc of the more bmp format support, and up-> down drawing
|
||||
if (!portapack::display.draw_bmp_from_sdcard_file({0, 0}, splash_dot_bmp))
|
||||
// ^ try draw bmp file from sdcard at (0,0), and the (0,0) already bypassed the status bar, so actual pos is (0, STATUS_BAR_HEIGHT)
|
||||
portapack::display.draw_bitmap({screen_width / 2 - ((bitmap_titlebar_image.size.width() * zoom) / 2),
|
||||
screen_height / 2},
|
||||
bitmap_titlebar_image.size,
|
||||
bitmap_titlebar_image.data,
|
||||
Theme::getInstance()->bg_darkest->foreground,
|
||||
Theme::getInstance()->bg_darkest->background, zoom);
|
||||
if (portapack::display.draw_bmp_from_sdcard_file({0, 0}, splash_dot_bmp)) return;
|
||||
// ^ try draw bmp file from sdcard at (0,0), and the (0,0) already bypassed the status bar, so actual pos is (0, STATUS_BAR_HEIGHT)
|
||||
|
||||
std::filesystem::path path{};
|
||||
get_random_splash_file(path);
|
||||
if (portapack::display.draw_bmp_from_sdcard_file({0, 0}, path)) return;
|
||||
portapack::display.draw_bitmap({screen_width / 2 - ((bitmap_titlebar_image.size.width() * 3) / 2),
|
||||
screen_height / 2},
|
||||
bitmap_titlebar_image.size,
|
||||
bitmap_titlebar_image.data,
|
||||
Theme::getInstance()->bg_darkest->foreground,
|
||||
Theme::getInstance()->bg_darkest->background, 3);
|
||||
// ^ draw BMP HEX arr in firmware, note that the BMP HEX arr only cover the image part (instead of fill the screen with background, this position is located it in the center)
|
||||
}
|
||||
|
||||
@@ -1082,7 +1131,6 @@ bool SplashScreenView::on_touch(const TouchEvent event) {
|
||||
case TouchEvent::Type::Start:
|
||||
handle_pop();
|
||||
return false;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -366,7 +366,8 @@ class SplashScreenView : public View {
|
||||
Button button_done{
|
||||
{screen_width, 0, 1, 1},
|
||||
""};
|
||||
// BMPViewer bmp_view{ {0, 0, screen_width, screen_height - 16}};
|
||||
uint32_t myrand(uint32_t* state);
|
||||
void get_random_splash_file(std::filesystem::path& path);
|
||||
};
|
||||
|
||||
class ReceiversMenuView : public BtnGridView {
|
||||
|
||||
@@ -53,3 +53,5 @@ const std::filesystem::path hopper_dir = u"HOPPER";
|
||||
const std::filesystem::path subghz_dir = u"SUBGHZ";
|
||||
const std::filesystem::path waterfalls_dir = u"WATERFALLS";
|
||||
const std::filesystem::path macaddress_dir = u"MACADDRESS";
|
||||
|
||||
const std::filesystem::path splash_dot_bmp = u"/splash.bmp";
|
||||
@@ -56,4 +56,6 @@ extern const std::filesystem::path subghz_dir;
|
||||
extern const std::filesystem::path waterfalls_dir;
|
||||
extern const std::filesystem::path macaddress_dir;
|
||||
|
||||
extern const std::filesystem::path splash_dot_bmp;
|
||||
|
||||
#endif /* __FILE_PATH_H__ */
|
||||
|
||||
Reference in New Issue
Block a user