Compare commits

..

9 Commits

Author SHA1 Message Date
sommermorgentraum 2d85e73f0d OokBrute app opt (#2561) 2025-03-11 21:17:47 +01:00
Mark Thompson 6ee7270db7 Setting for faster Button Repeat delays (#2559)
* Setting for faster Button Repeat delays

* Tweak fast delay times

* Tweak delay times

* Added description line and tweaked delay again
2025-03-11 09:13:41 -05:00
Mark Thompson b4112f0c04 Remove deprecated QR Code code (#2558) 2025-03-10 19:13:57 +00:00
Mark Thompson e920932886 Snake icon change (#2557) 2025-03-10 12:37:30 -05:00
Mark Thompson 081b11ad41 Breakout icon change (#2556)
- Changed Breakout icon
- Changed Tetris icon color to green
2025-03-10 17:25:49 +01:00
gullradriel adc23315a2 updated bitmaps for speaker icon (#2555)
* updated bitmaps for speaker icon
* removed opera cake icon that was added by mistake
* adding missing Game menu source png
* cyan for Game menu
* regenerated icons
2025-03-10 12:33:33 +01:00
Mark Thompson 084b88564b Stopwatch external app (#2553) 2025-03-09 22:03:41 +01:00
dark-juju 24e9504688 Moved speaker 1px to the right to match muted icon variant. (#2554) 2025-03-09 21:02:48 +00:00
sommermorgentraum c670ca59a8 rename rand pwd app (#2552)
* _

* remove wip code that forgot to add in old branch
2025-03-08 21:38:12 -06:00
26 changed files with 830 additions and 300 deletions
+31 -27
View File
@@ -674,32 +674,6 @@ void SetAudioView::focus() {
button_save.focus();
}
/* SetQRCodeView *****************************************/
SetQRCodeView::SetQRCodeView(NavigationView& nav) {
add_children({
&labels,
&checkbox_bigger_qr,
&button_save,
&button_cancel,
});
checkbox_bigger_qr.set_value(pmem::show_bigger_qr_code());
button_save.on_select = [&nav, this](Button&) {
pmem::set_show_bigger_qr_code(checkbox_bigger_qr.value());
nav.pop();
};
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
}
void SetQRCodeView::focus() {
button_save.focus();
}
/* SetEncoderDialView ************************************/
SetEncoderDialView::SetEncoderDialView(NavigationView& nav) {
@@ -747,6 +721,36 @@ void SetEncoderDialView::focus() {
button_save.focus();
}
/* SetButtonsView ************************************/
SetButtonsView::SetButtonsView(NavigationView& nav) {
add_children({&labels,
&button_save,
&button_cancel,
&field_repeat_delay,
&field_repeat_speed,
&field_long_press_delay});
field_repeat_delay.set_by_value(pmem::ui_button_repeat_delay());
field_repeat_speed.set_by_value(pmem::ui_button_repeat_speed());
field_long_press_delay.set_by_value(pmem::ui_button_long_press_delay());
button_save.on_select = [&nav, this](Button&) {
pmem::set_ui_button_repeat_delay(field_repeat_delay.selected_index_value());
pmem::set_ui_button_repeat_speed(field_repeat_speed.selected_index_value());
pmem::set_ui_button_long_press_delay(field_long_press_delay.selected_index_value());
nav.pop();
};
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
}
void SetButtonsView::focus() {
button_save.focus();
}
/* AppSettingsView ************************************/
AppSettingsView::AppSettingsView(
@@ -1093,12 +1097,12 @@ void SettingsMenuView::on_populate() {
{"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push<SetConverterSettingsView>(); }},
{"Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [this]() { nav_.push<SetDateTimeView>(); }},
{"Encoder Dial", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetEncoderDialView>(); }},
{"Button Speed", ui::Color::dark_cyan(), &bitmap_icon_controls, [this]() { nav_.push<SetButtonsView>(); }},
{"Freq. Correct", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push<SetFrequencyCorrectionView>(); }},
{"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push<SetPersistentMemoryView>(); }},
{"Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push<SetRadioView>(); }},
{"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [this]() { nav_.push<SetSDCardView>(); }},
{"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [this]() { nav_.push<SetUIView>(); }},
//{"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [this]() { nav_.push<SetQRCodeView>(); }},
{"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>(); }},
+43 -29
View File
@@ -545,35 +545,6 @@ class SetAudioView : public View {
};
};
class SetQRCodeView : public View {
public:
SetQRCodeView(NavigationView& nav);
void focus() override;
std::string title() const override { return "QR Code"; };
private:
Labels labels{
{{1 * 8, 1 * 16}, "Change the size of the QR", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "code shown in Radiosonde.", Theme::getInstance()->fg_light->foreground},
};
Checkbox checkbox_bigger_qr{
{3 * 8, 4 * 16},
20,
"Show large QR code"};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
};
using portapack::persistent_memory::encoder_dial_direction;
using portapack::persistent_memory::encoder_dial_sensitivity;
using portapack::persistent_memory::encoder_rate_multiplier;
@@ -644,6 +615,49 @@ class SetEncoderDialView : public View {
};
};
class SetButtonsView : public View {
public:
SetButtonsView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Button Speed"; };
private:
Labels labels{
{{1 * 8, 1 * 16}, "Adjusts response time when a", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "button is held down.", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 5 * 16}, "Repeat delay:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 16}, "Repeat speed:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 9 * 16}, "Long press delay:", Theme::getInstance()->fg_light->foreground},
};
OptionsField field_repeat_delay{
{20 * 8, 5 * 16},
6,
{{"NORMAL", false},
{"FAST", true}}};
OptionsField field_repeat_speed{
{20 * 8, 7 * 16},
6,
{{"NORMAL", false},
{"FAST", true}}};
OptionsField field_long_press_delay{
{20 * 8, 9 * 16},
6,
{{"NORMAL", false},
{"FAST", true}}};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
};
class SetPersistentMemoryView : public View {
public:
SetPersistentMemoryView(NavigationView& nav);
+237 -86
View File
@@ -105,44 +105,6 @@ static constexpr Bitmap bitmap_icon_utilities{
{16, 16},
bitmap_icon_utilities_data};
static constexpr uint8_t bitmap_icon_games_data[] = {
0x0C,
0x0C,
0x0C,
0x0C,
0x3F,
0x3C,
0xFF,
0x7E,
0xFF,
0xFF,
0xFF,
0xFF,
0xCC,
0xCC,
0xCC,
0xCC,
0xFF,
0xFF,
0xE7,
0x73,
0xE7,
0x73,
0x33,
0x33,
0x03,
0x30,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
static constexpr Bitmap bitmap_icon_games{
{16, 16},
bitmap_icon_games_data};
static constexpr uint8_t bitmap_stripes_data[] = {
0xFF,
0x03,
@@ -287,6 +249,44 @@ static constexpr Bitmap bitmap_icon_file_wav{
{16, 16},
bitmap_icon_file_wav_data};
static constexpr uint8_t bitmap_icon_games_data[] = {
0x00,
0x01,
0x00,
0x01,
0x80,
0x00,
0x80,
0x00,
0x80,
0x00,
0xFE,
0x7F,
0xFF,
0xFF,
0xFF,
0xFF,
0xE7,
0xD7,
0xE7,
0x93,
0x81,
0xFF,
0x81,
0x93,
0xE7,
0xD7,
0xE7,
0xFF,
0x3F,
0xF9,
0xFE,
0x7F,
};
static constexpr Bitmap bitmap_icon_games{
{16, 16},
bitmap_icon_games_data};
static constexpr uint8_t bitmap_icon_tetra_data[] = {
0xE0,
0x0F,
@@ -402,23 +402,23 @@ static constexpr Bitmap bitmap_icon_downconvert{
bitmap_icon_downconvert_data};
static constexpr uint8_t bitmap_icon_speaker_and_headphones_data[] = {
0x20,
0x40,
0x10,
0x30,
0x60,
0x20,
0x38,
0x70,
0x44,
0x3E,
0x7C,
0x48,
0x3E,
0x7C,
0x91,
0x3E,
0x7C,
0x92,
0x38,
0x70,
0x92,
0x30,
0x60,
0x92,
0x20,
0x40,
0x92,
0x00,
0x92,
@@ -1025,6 +1025,44 @@ static constexpr Bitmap bitmap_icon_previous{
{16, 16},
bitmap_icon_previous_data};
static constexpr uint8_t bitmap_icon_tools_antenna_data[] = {
0x38,
0x3E,
0x10,
0x22,
0x10,
0x26,
0x10,
0x22,
0x10,
0x2E,
0x10,
0x22,
0x10,
0x26,
0x10,
0x22,
0x38,
0x2E,
0x38,
0x22,
0x38,
0x26,
0x38,
0x22,
0x38,
0x2E,
0x38,
0x22,
0x38,
0x3E,
0x00,
0x00,
};
static constexpr Bitmap bitmap_icon_tools_antenna{
{16, 16},
bitmap_icon_tools_antenna_data};
static constexpr uint8_t bitmap_icon_batt_text_data[] = {
0x00,
0x00,
@@ -1651,6 +1689,44 @@ static constexpr Bitmap bitmap_icon_qr_code{
{16, 16},
bitmap_icon_qr_code_data};
static constexpr uint8_t bitmap_stopwatch_data[] = {
0x00,
0x00,
0xC0,
0x01,
0x80,
0x00,
0x80,
0x20,
0x60,
0x13,
0x10,
0x0C,
0x88,
0x08,
0x84,
0x10,
0x84,
0x10,
0xC2,
0x21,
0x84,
0x10,
0x04,
0x10,
0x08,
0x08,
0x10,
0x04,
0x60,
0x03,
0x80,
0x00,
};
static constexpr Bitmap bitmap_stopwatch{
{16, 16},
bitmap_stopwatch_data};
static constexpr uint8_t bitmap_icon_sonde_data[] = {
0x80,
0x03,
@@ -1799,45 +1875,6 @@ static constexpr uint8_t bitmap_icon_lge_data[] = {
0x00,
0x00,
};
static constexpr uint8_t bitmap_icon_file_iq_data[] = {
0xFC,
0x03,
0x04,
0x06,
0x04,
0x0E,
0x04,
0x1E,
0x04,
0x3E,
0x04,
0x20,
0x04,
0x20,
0x04,
0x21,
0x44,
0x25,
0x54,
0x25,
0xF4,
0x2F,
0xA4,
0x2A,
0x84,
0x22,
0x04,
0x22,
0x04,
0x20,
0xFC,
0x3F,
};
static constexpr Bitmap bitmap_icon_file_iq{
{16, 16},
bitmap_icon_file_iq_data};
static constexpr Bitmap bitmap_icon_lge{
{16, 16},
bitmap_icon_lge_data};
@@ -1918,6 +1955,82 @@ static constexpr Bitmap bitmap_icon_tetris{
{16, 16},
bitmap_icon_tetris_data};
static constexpr uint8_t bitmap_icon_breakout_data[] = {
0x00,
0x00,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x00,
0x00,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0x00,
0x00,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x00,
0x00,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
};
static constexpr Bitmap bitmap_icon_breakout{
{16, 16},
bitmap_icon_breakout_data};
static constexpr uint8_t bitmap_icon_snake_data[] = {
0x00,
0x00,
0x00,
0x00,
0xE0,
0x09,
0x70,
0xC7,
0xFC,
0xC9,
0x06,
0x00,
0x06,
0x00,
0x0C,
0x00,
0xF0,
0x01,
0x00,
0x3E,
0x00,
0x40,
0xFC,
0x40,
0x02,
0x3F,
0x02,
0x00,
0x7C,
0x80,
0x80,
0x7F,
};
static constexpr Bitmap bitmap_icon_snake{
{16, 16},
bitmap_icon_snake_data};
static constexpr uint8_t bitmap_icon_rename_data[] = {
0x00,
0x00,
@@ -2752,6 +2865,44 @@ static constexpr Bitmap bitmap_icon_touchtunes{
{16, 16},
bitmap_icon_touchtunes_data};
static constexpr uint8_t bitmap_icon_file_iq_data[] = {
0xFC,
0x03,
0x04,
0x06,
0x04,
0x0E,
0x04,
0x1E,
0x04,
0x3E,
0x04,
0x20,
0x04,
0x20,
0x04,
0x21,
0x44,
0x25,
0x54,
0x25,
0xF4,
0x2F,
0xA4,
0x2A,
0x84,
0x22,
0x04,
0x22,
0x04,
0x20,
0xFC,
0x3F,
};
static constexpr Bitmap bitmap_icon_file_iq{
{16, 16},
bitmap_icon_file_iq_data};
static constexpr uint8_t bitmap_icon_sd_data[] = {
0x00,
0x00,
+32 -32
View File
@@ -27,38 +27,38 @@ __attribute__((section(".external_app.app_breakout.application_information"), us
/*.app_name = */ "Breakout",
/*.bitmap_data = */ {
0xFF,
0xFF,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0xFF,
0xFF,
0x80,
0x80,
0x80,
0x80,
0x80,
0x80,
0xFF,
0xFF,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0xFF,
0xFF,
0x80,
0x80,
0x80,
0x80,
0x80,
0x80,
0x00,
0x00,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x00,
0x00,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0x00,
0x00,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x7F,
0x00,
0x00,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
0xF7,
},
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::GAMES,
+13 -8
View File
@@ -117,7 +117,7 @@ set(EXTCPPSRC
#shoppingcart_lock
external/shoppingcart_lock/main.cpp
external/shoppingcart_lock/shoppingcart_lock.cpp
external/shoppingcart_lock/shoppingcart_lock.cpp
#ookbrute
external/ookbrute/main.cpp
@@ -129,8 +129,8 @@ set(EXTCPPSRC
#cvs_spam
external/cvs_spam/main.cpp
external/cvs_spam/cvs_spam.cpp
external/cvs_spam/cvs_spam.cpp
#flippertx
external/flippertx/main.cpp
external/flippertx/ui_flippertx.cpp
@@ -142,15 +142,15 @@ set(EXTCPPSRC
#mcu_temperature
external/mcu_temperature/main.cpp
external/mcu_temperature/mcu_temperature.cpp
#fmradio
external/fmradio/main.cpp
external/fmradio/ui_fmradio.cpp
#tuner
external/tuner/main.cpp
external/tuner/ui_tuner.cpp
#metronome
external/metronome/main.cpp
external/metronome/ui_metronome.cpp
@@ -162,8 +162,8 @@ set(EXTCPPSRC
#hopper
external/hopper/main.cpp
external/hopper/ui_hopper.cpp
# whip calculator
# whip calculator
external/antenna_length/main.cpp
external/antenna_length/ui_whipcalc.cpp
@@ -178,6 +178,10 @@ set(EXTCPPSRC
# playlist editor
external/playlist_editor/main.cpp
external/playlist_editor/ui_playlist_editor.cpp
#stopwatch
external/stopwatch/main.cpp
external/stopwatch/ui_stopwatch.cpp
)
set(EXTAPPLIST
@@ -224,4 +228,5 @@ set(EXTAPPLIST
view_wav
sd_wipe
playlist_editor
stopwatch
)
+27 -21
View File
@@ -48,24 +48,25 @@ MEMORY
ram_external_app_sstvtx(rwx) : org = 0xADC70000, len = 32k
ram_external_app_random_password(rwx) : org = 0xADC80000, len = 32k
ram_external_app_acars_rx(rwx) : org = 0xADC90000, len = 32k
ram_external_app_shoppingcart_lock(rwx) : org = 0xADCA0000, len = 32k
ram_external_app_cvs_spam(rwx) : org = 0xADCB0000, len = 32k
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
ram_external_app_mcu_temperature(rwx) : org = 0xADD00000, len = 32k
ram_external_app_fmradio(rwx) : org = 0xADD10000, len = 32k
ram_external_app_shoppingcart_lock(rwx) : org = 0xADCA0000, len = 32k
ram_external_app_cvs_spam(rwx) : org = 0xADCB0000, len = 32k
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
ram_external_app_mcu_temperature(rwx) : org = 0xADD00000, len = 32k
ram_external_app_fmradio(rwx) : org = 0xADD10000, len = 32k
ram_external_app_tuner(rwx) : org = 0xADD20000, len = 32k
ram_external_app_metronome(rwx) : org = 0xADD30000, len = 32k
ram_external_app_app_manager(rwx) : org = 0xADD40000, len = 32k
ram_external_app_hopper(rwx) : org = 0xADD50000, len = 32k
ram_external_app_antenna_length(rwx) : org = 0xADD60000, len = 32k
ram_external_app_view_wav(rwx) : org = 0xADD70000, len = 32k
ram_external_app_sd_wipe(rwx) : org = 0xADD80000, len = 32k
ram_external_app_playlist_editor(rwx) : org = 0xADD90000, len = 32k
ram_external_app_metronome(rwx) : org = 0xADD30000, len = 32k
ram_external_app_app_manager(rwx) : org = 0xADD40000, len = 32k
ram_external_app_hopper(rwx) : org = 0xADD50000, len = 32k
ram_external_app_antenna_length(rwx) : org = 0xADD60000, len = 32k
ram_external_app_view_wav(rwx) : org = 0xADD70000, len = 32k
ram_external_app_sd_wipe(rwx) : org = 0xADD80000, len = 32k
ram_external_app_playlist_editor(rwx) : org = 0xADD90000, len = 32k
ram_external_app_breakout(rwx) : org = 0xADDA0000, len = 32k
ram_external_app_snake(rwx) : org = 0xADDB0000, len = 32k
ram_external_app_snake(rwx) : org = 0xADDB0000, len = 32k
ram_external_app_stopwatch(rwx) : org = 0xADDC0000, len = 32k
}
SECTIONS
@@ -158,13 +159,13 @@ SECTIONS
{
KEEP(*(.external_app.app_breakout.application_information));
*(*ui*external_app*breakout*);
} > ram_external_app_breakout
} > ram_external_app_breakout
.external_app_snake : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_snake.application_information));
*(*ui*external_app*snake*);
} > ram_external_app_snake
} > ram_external_app_snake
.external_app_extsensors : ALIGN(4) SUBALIGN(4)
{
@@ -208,7 +209,6 @@ SECTIONS
*(*ui*external_app*adsbtx*);
} > ram_external_app_adsbtx
.external_app_morse_tx : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_morse_tx.application_information));
@@ -274,13 +274,13 @@ SECTIONS
KEEP(*(.external_app.app_mcu_temperature.application_information));
*(*ui*external_app*mcu_temperature*);
} > ram_external_app_mcu_temperature
.external_app_fmradio : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_fmradio.application_information));
*(*ui*external_app*fmradio*);
} > ram_external_app_fmradio
.external_app_tuner : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_tuner.application_information));
@@ -328,4 +328,10 @@ SECTIONS
KEEP(*(.external_app.app_playlist_editor.application_information));
*(*ui*external_app*playlist_editor*);
} > ram_external_app_playlist_editor
.external_app_stopwatch : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_stopwatch.application_information));
*(*ui*external_app*stopwatch*);
} > ram_external_app_stopwatch
}
+39
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2024 HTotoo
* copyleft Whiterose of the Dark Army
*
* This file is part of PortaPack.
*
@@ -25,6 +26,7 @@
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "portapack_persistent_memory.hpp"
#include "ui_textentry.hpp"
using namespace portapack;
using namespace ui;
@@ -39,6 +41,9 @@ OOKBruteView::OOKBruteView(NavigationView& nav)
: nav_{nav} {
add_children({
&button_startstop,
&button_input_stop_position,
&button_input_start_position,
&labels,
&field_frequency,
&tx_view,
&options_atkmode,
@@ -66,6 +71,40 @@ OOKBruteView::OOKBruteView(NavigationView& nav)
field_stop.on_change = [this](int32_t) {
validate_start_stop();
};
button_input_start_position.on_select = [this](Button&) {
stop(); // prevent mess count var up
text_input_buffer = to_string_dec_uint(field_start.value());
if (text_input_buffer == "0") {
text_input_buffer = "";
}
text_prompt(
nav_,
text_input_buffer,
8, // currently longest is princeton
[this](std::string& buffer) {
field_start.set_value(atoi(buffer.c_str()));
validate_start_stop();
});
};
button_input_stop_position.on_select = [this](Button&) {
stop(); // prevent mess count var up
text_input_buffer = to_string_dec_uint(field_stop.value());
if (text_input_buffer == "0") {
text_input_buffer = "";
}
text_prompt(
nav_,
text_input_buffer,
8, // currently longest is princeton
[this](std::string& buffer) {
field_stop.set_value(atoi(buffer.c_str()));
validate_start_stop();
});
};
update_start_stop(0);
}
+21 -4
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2024 HTotoo
* copyleft Whiterose of the Dark Army
*
* This file is part of PortaPack.
*
@@ -52,12 +53,25 @@ class OOKBruteView : public View {
app_settings::SettingsManager settings_{
"tx_ookbrute", app_settings::Mode::TX};
Labels labels{
{{0 * 8, 2 * 16}, "Start Position:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "Stop Position:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, "Encoder Type:", Theme::getInstance()->fg_light->foreground}};
Button button_startstop{
{0, 3 * 16, 96, 24},
{8, screen_height - 48 - 16, screen_width - 2 * 8, 48},
LanguageHelper::currentMessages[LANG_START]};
Button button_input_start_position{
{8, 4 * 16, screen_width - 2 * 8, 24},
"Input Start Pos"};
Button button_input_stop_position{
{8, 9 * 16, screen_width - 2 * 8, 24},
"Input Stop Pos"};
NumberField field_start{
{0 * 8, 1 * 16},
{0 * 8, 3 * 16},
8,
{0, 2500},
1,
@@ -65,15 +79,16 @@ class OOKBruteView : public View {
true};
NumberField field_stop{
{11 * 8, 1 * 16},
{0, 8 * 16},
9,
{0, 2500},
1,
' ',
true};
// NB: when add new encoder here you should also change the char count limit for input range buttons by it's digits in DEC
OptionsField options_atkmode{
{0 * 8, 2 * 16},
{0, 14 * 16},
12,
{{"Came12", 0},
{"Came24", 1},
@@ -86,6 +101,8 @@ class OOKBruteView : public View {
uint32_t counter = 0; // for packet change
std::string text_input_buffer{}; // this is needed by the text_prompt func
void start();
void stop();
+1 -1
View File
@@ -38,7 +38,7 @@ __attribute__((section(".external_app.app_random_password.application_informatio
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "Random passwd",
/*.app_name = */ "Rand Pwd",
/*.bitmap_data = */ {
0xC0,
0x03,
+22 -21
View File
@@ -28,35 +28,36 @@ __attribute__((section(".external_app.app_snake.application_information"), used)
{
0x00,
0x00,
0x7E,
0x42,
0x42,
0x42,
0x7E,
0x00,
0x00,
0x7E,
0x42,
0x42,
0x42,
0x7E,
0xE0,
0x09,
0x70,
0xC7,
0xFC,
0xC9,
0x06,
0x00,
0x06,
0x00,
0x0C,
0x00,
0x7E,
0x42,
0x42,
0x42,
0x7E,
0xF0,
0x01,
0x00,
0x3E,
0x00,
0x7E,
0x42,
0x42,
0x42,
0x7E,
0x00,
0x40,
0xFC,
0x40,
0x02,
0x3F,
0x02,
0x00,
0x7C,
0x80,
0x80,
0x7F,
},
ui::Color::green().v,
app_location_t::GAMES,
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2025 Mark Thompson
*
* 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_stopwatch.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::stopwatch {
void initialize_app(ui::NavigationView& nav) {
nav.push<StopwatchView>();
}
} // namespace ui::external_app::stopwatch
extern "C" {
__attribute__((section(".external_app.app_stopwatch.application_information"), used)) application_information_t _application_information_stopwatch = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::stopwatch::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "Stopwatch",
/*.bitmap_data = */ {
0x00,
0x00,
0xC0,
0x01,
0x80,
0x00,
0x80,
0x20,
0x60,
0x13,
0x10,
0x0C,
0x88,
0x08,
0x84,
0x10,
0x84,
0x10,
0xC2,
0x21,
0x84,
0x10,
0x04,
0x10,
0x08,
0x08,
0x10,
0x04,
0x60,
0x03,
0x80,
0x00,
},
/*.icon_color = */ ui::Color::cyan().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
};
}
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright 2025 Mark Thompson
*
* 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_stopwatch.hpp"
#include "portapack.hpp"
#include "ch.h"
using namespace portapack;
namespace ui::external_app::stopwatch {
StopwatchView::StopwatchView(NavigationView& nav) {
add_children({
&labels,
&button_run_stop,
&button_reset_lap,
&button_done,
&big_display,
&lap_display,
});
button_run_stop.on_select = [this](Button&) {
if (running)
stop();
else
run();
};
button_reset_lap.on_select = [this](Button&) {
if (running)
lap();
else
reset();
};
button_done.on_select = [&nav](Button&) {
nav.pop();
};
}
void StopwatchView::focus() {
button_run_stop.focus();
}
void StopwatchView::run() {
running = true;
start_time = chTimeNow() - previously_elapsed;
button_run_stop.set_text("STOP");
button_reset_lap.set_text("LAP");
}
void StopwatchView::stop() {
running = false;
end_time = chTimeNow();
previously_elapsed = end_time - start_time;
button_run_stop.set_text("START");
button_reset_lap.set_text("RESET");
}
void StopwatchView::reset() {
lap_time = end_time = start_time = previously_elapsed = 0;
big_display.set(0);
lap_display.set(0);
}
void StopwatchView::lap() {
lap_time = chTimeNow();
lap_display.set((lap_time - start_time) * 1000); // convert elapsed time in ms to MHz for BigFrequency widget
}
void StopwatchView::paint(Painter& painter) {
(void)painter;
if (running) {
end_time = chTimeNow();
big_display.set((end_time - start_time) * 1000); // convert elapsed time in ms to MHz for BigFrequency widget
}
}
void StopwatchView::frame_sync() {
set_dirty();
}
} // namespace ui::external_app::stopwatch
@@ -0,0 +1,83 @@
/*
* Copyright 2025 Mark Thompson
*
* 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_STOPWATCH_H__
#define __UI_STOPWATCH_H__
#include "ui_navigation.hpp"
namespace ui::external_app::stopwatch {
class StopwatchView : public View {
public:
StopwatchView(NavigationView& nav);
void focus() override;
void paint(Painter& painter) override;
void frame_sync();
std::string title() const override { return "Stopwatch"; };
private:
void run();
void stop();
void reset();
void lap();
bool running{false};
long long start_time{0};
long long end_time{0};
long long lap_time{0};
long long previously_elapsed{0};
Labels labels{
{{0 * 8, 1 * 16}, "TOTAL:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "LAP:", Theme::getInstance()->fg_light->foreground},
};
BigFrequency big_display{
{4, 2 * 16 + 4, 28 * 8, 52},
0};
BigFrequency lap_display{
{4, 8 * 16 + 4, 28 * 8, 52},
0};
Button button_run_stop{
{72, 210, 96, 24},
"START"};
Button button_reset_lap{
{72, 240, 96, 24},
"RESET"};
Button button_done{
{72, 270, 96, 24},
"EXIT"};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->frame_sync();
}};
};
} // namespace ui::external_app::stopwatch
#endif /*__UI_STOPWATCH_H__*/
+1 -1
View File
@@ -73,7 +73,7 @@ __attribute__((section(".external_app.app_tetris.application_information"), used
0xFF,
0xF1,
},
/*.icon_color = */ ui::Color::orange().v,
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::GAMES,
/*.desired_menu_position = */ -1,
+3 -3
View File
@@ -84,7 +84,7 @@ bool Debounce::feed(const uint8_t bit) {
// (by toggling reported state every 1/2 of the delay time)
if (--repeat_ctr_ == 0) {
state_to_report_ = !state_to_report_;
repeat_ctr_ = REPEAT_SUBSEQUENT_DELAY / 2;
repeat_ctr_ = portapack::persistent_memory::ui_button_repeat_speed() ? REPEAT_SUBSEQUENT_DELAY_FAST / 2 : REPEAT_SUBSEQUENT_DELAY_NORMAL / 2;
return true;
}
}
@@ -96,7 +96,7 @@ bool Debounce::feed(const uint8_t bit) {
// if LONG_PRESS_DELAY is reached then finally report that switch is pressed and set flag
// indicating it was a LONG press
// (note that repeat_support and long_press support are mutually exclusive)
if (held_time_ >= LONG_PRESS_DELAY) {
if (held_time_ >= (portapack::persistent_memory::ui_button_long_press_delay() ? LONG_PRESS_DELAY_FAST : LONG_PRESS_DELAY_NORMAL)) {
pulse_upon_release_ = false;
long_press_occurred_ = true;
state_to_report_ = 1;
@@ -104,7 +104,7 @@ bool Debounce::feed(const uint8_t bit) {
}
} else if (repeat_enabled_ && !long_press_enabled_) {
// Repeat support -- 4 directional buttons only (unless long_press is enabled)
if (held_time_ >= REPEAT_INITIAL_DELAY) {
if (held_time_ >= (portapack::persistent_memory::ui_button_repeat_delay() ? REPEAT_INITIAL_DELAY_FAST : REPEAT_INITIAL_DELAY_NORMAL)) {
// Delay reached; trigger repeat code on NEXT tick
repeat_ctr_ = 1;
held_time_ = 0;
+7 -3
View File
@@ -30,9 +30,13 @@
#define DEBOUNCE_MASK ((1 << DEBOUNCE_COUNT) - 1)
// # of timer0 ticks before a held button starts being counted as repeated presses
#define REPEAT_INITIAL_DELAY 250
#define REPEAT_SUBSEQUENT_DELAY 92
#define LONG_PRESS_DELAY 800
#define REPEAT_INITIAL_DELAY_NORMAL 250
#define REPEAT_SUBSEQUENT_DELAY_NORMAL 92
#define LONG_PRESS_DELAY_NORMAL 800
#define REPEAT_INITIAL_DELAY_FAST 188
#define REPEAT_SUBSEQUENT_DELAY_FAST 66
#define LONG_PRESS_DELAY_FAST 555
class Debounce {
public:
+1 -1
View File
@@ -126,7 +126,7 @@ const NavigationView::AppList NavigationView::appList = {
{"microphone", "Microphone", HOME, Color::green(), &bitmap_icon_microphone, new ViewFactory<MicTXView>()},
{"lookingglass", "Looking Glass", HOME, Color::green(), &bitmap_icon_looking, new ViewFactory<GlassView>()},
{nullptr, "Utilities", HOME, Color::cyan(), &bitmap_icon_utilities, new ViewFactory<UtilitiesMenuView>()},
{nullptr, "Games", HOME, Color::purple(), &bitmap_icon_games, new ViewFactory<GamesMenuView>()},
{nullptr, "Games", HOME, Color::cyan(), &bitmap_icon_games, new ViewFactory<GamesMenuView>()},
{nullptr, "Settings", HOME, Color::cyan(), &bitmap_icon_setup, new ViewFactory<SettingsMenuView>()},
/* RX ********************************************************************/
{"adsbrx", "ADS-B", RX, Color::green(), &bitmap_icon_adsb, new ViewFactory<ADSBRxView>()},
+25 -13
View File
@@ -103,7 +103,7 @@ struct ui_config_t {
uint8_t show_gui_return_icon : 1;
uint8_t load_app_settings : 1;
uint8_t save_app_settings : 1;
uint8_t show_large_qr_code : 1;
uint8_t UNUSED_7 : 1; // Deprecated, but bit can be set by older firmware
bool disable_touchscreen : 1;
bool hide_clock : 1;
@@ -134,9 +134,9 @@ struct ui_config2_t {
bool hide_numeric_battery : 1;
bool hide_battery_icon : 1;
bool override_batt_calc : 1;
bool UNUSED_4 : 1;
bool UNUSED_5 : 1;
bool UNUSED_6 : 1;
bool button_repeat_delay : 1;
bool button_repeat_speed : 1;
bool button_long_press_delay : 1;
uint8_t theme_id;
uint8_t PLACEHOLDER_3;
@@ -603,10 +603,6 @@ bool show_gui_return_icon() { // add return icon in touchscreen menu
return data->ui_config.show_gui_return_icon != 0;
}
bool show_bigger_qr_code() { // show bigger QR code
return data->ui_config.show_large_qr_code != 0;
}
bool disable_touchscreen() { // Option to disable touch screen
return data->ui_config.disable_touchscreen;
}
@@ -684,10 +680,6 @@ void set_save_app_settings(bool v) {
data->ui_config.save_app_settings = v ? 1 : 0;
}
void set_show_bigger_qr_code(bool v) {
data->ui_config.show_large_qr_code = v ? 1 : 0;
}
void set_disable_touchscreen(bool v) {
data->ui_config.disable_touchscreen = v;
}
@@ -963,6 +955,15 @@ uint8_t ui_theme_id() {
bool ui_override_batt_calc() {
return data->ui_config2.override_batt_calc;
}
bool ui_button_repeat_delay() {
return data->ui_config2.button_repeat_delay;
}
bool ui_button_repeat_speed() {
return data->ui_config2.button_repeat_speed;
}
bool ui_button_long_press_delay() {
return data->ui_config2.button_long_press_delay;
}
void set_ui_hide_speaker(bool v) {
data->ui_config2.hide_speaker = v;
@@ -1008,6 +1009,15 @@ void set_ui_theme_id(uint8_t theme_id) {
void set_ui_override_batt_calc(bool v) {
data->ui_config2.override_batt_calc = v;
}
void set_ui_button_repeat_delay(bool v) {
data->ui_config2.button_repeat_delay = v;
}
void set_ui_button_repeat_speed(bool v) {
data->ui_config2.button_repeat_speed = v;
}
void set_ui_button_long_press_delay(bool v) {
data->ui_config2.button_long_press_delay = v;
}
/* Converter */
bool config_converter() {
@@ -1270,7 +1280,6 @@ bool debug_dump() {
pmem_dump_file.write_line("ui_config show_gui_return_icon: " + to_string_dec_uint(data->ui_config.show_gui_return_icon));
pmem_dump_file.write_line("ui_config load_app_settings: " + to_string_dec_uint(data->ui_config.load_app_settings));
pmem_dump_file.write_line("ui_config save_app_settings: " + to_string_dec_uint(data->ui_config.save_app_settings));
pmem_dump_file.write_line("ui_config show_bigger_qr_code: " + to_string_dec_uint(data->ui_config.show_large_qr_code));
pmem_dump_file.write_line("ui_config disable_touchscreen: " + to_string_dec_uint(data->ui_config.disable_touchscreen));
pmem_dump_file.write_line("ui_config hide_clock: " + to_string_dec_uint(data->ui_config.hide_clock));
pmem_dump_file.write_line("ui_config clock_with_date: " + to_string_dec_uint(data->ui_config.clock_show_date));
@@ -1295,6 +1304,9 @@ bool debug_dump() {
pmem_dump_file.write_line("ui_config2 hide_numeric_battery: " + to_string_dec_uint(data->ui_config2.hide_numeric_battery));
pmem_dump_file.write_line("ui_config2 theme_id: " + to_string_dec_uint(data->ui_config2.theme_id));
pmem_dump_file.write_line("ui_config2 override_batt_calc: " + to_string_dec_uint(data->ui_config2.override_batt_calc));
pmem_dump_file.write_line("ui_config2 button_repeat_delay: " + to_string_dec_uint(data->ui_config2.button_repeat_delay));
pmem_dump_file.write_line("ui_config2 button_repeat_speed: " + to_string_dec_uint(data->ui_config2.button_repeat_speed));
pmem_dump_file.write_line("ui_config2 button_long_press_delay: " + to_string_dec_uint(data->ui_config2.button_long_press_delay));
// misc_config bits
pmem_dump_file.write_line("misc_config config_audio_mute: " + to_string_dec_int(config_audio_mute()));
@@ -205,7 +205,6 @@ bool config_converter();
bool config_updown_converter();
int64_t config_converter_freq();
bool show_gui_return_icon();
bool show_bigger_qr_code();
bool hide_clock();
bool clock_with_date();
bool config_login();
@@ -217,7 +216,6 @@ bool disable_touchscreen();
void set_gui_return_icon(bool v);
void set_load_app_settings(bool v);
void set_save_app_settings(bool v);
void set_show_bigger_qr_code(bool v);
void set_config_disable_external_tcxo(bool v);
void set_config_sdcard_high_speed_io(bool v, bool save);
void set_config_disable_config_mode(bool v);
@@ -342,6 +340,9 @@ bool ui_hide_battery_icon();
bool ui_hide_sd_card();
uint8_t ui_theme_id();
bool ui_override_batt_calc();
bool ui_button_repeat_delay();
bool ui_button_repeat_speed();
bool ui_button_long_press_delay();
void set_ui_hide_speaker(bool v);
void set_ui_hide_mute(bool v);
void set_ui_hide_converter(bool v);
@@ -356,6 +357,9 @@ void set_ui_hide_battery_icon(bool v);
void set_ui_hide_sd_card(bool v);
void set_ui_theme_id(uint8_t v);
void set_ui_override_batt_calc(bool v);
void set_ui_button_repeat_delay(bool v);
void set_ui_button_repeat_speed(bool v);
void set_ui_button_long_press_delay(bool v);
// sd persisting settings
bool should_use_sdcard_for_pmem();
+53 -48
View File
@@ -528,58 +528,63 @@ void BigFrequency::paint(Painter& painter) {
Point digit_pos;
ui::Color segment_color;
const auto rect = screen_rect();
if (_frequency != _previous_frequency) {
_previous_frequency = _frequency;
// Erase
painter.fill_rectangle(
{{0, rect.location().y()}, {screen_width, 52}},
Theme::getInstance()->bg_darkest->background);
rf::Frequency frequency{_frequency};
const auto rect = screen_rect();
// Prepare digits
if (!_frequency) {
digits.fill(10); // ----.---
digit_pos = {0, rect.location().y()};
} else {
_frequency /= 1000; // GMMM.KKK(uuu)
// Erase
painter.fill_rectangle(
{{0, rect.location().y()}, {screen_width, 52}},
Theme::getInstance()->bg_darkest->background);
for (i = 0; i < 7; i++) {
digits[6 - i] = _frequency % 10;
_frequency /= 10;
}
// Remove leading zeros
for (i = 0; i < 3; i++) {
if (!digits[i])
digits[i] = 16; // "Don't draw" code
else
break;
}
digit_pos = {(Coord)(240 - ((7 * digit_width) + 8) - (i * digit_width)) / 2, rect.location().y()};
}
segment_color = style().foreground;
// Draw
for (i = 0; i < 7; i++) {
digit = digits[i];
if (digit < 16) {
digit_def = segment_font[(uint8_t)digit];
for (size_t s = 0; s < 7; s++) {
if (digit_def & 1)
painter.fill_rectangle({digit_pos + segments[s].location(), segments[s].size()}, segment_color);
digit_def >>= 1;
}
}
if (i == 3) {
// Dot
painter.fill_rectangle({digit_pos + Point(34, 48), {4, 4}}, segment_color);
digit_pos += {(digit_width + 8), 0};
// Prepare digits
if (!frequency) {
digits.fill(10); // ----.---
digit_pos = {0, rect.location().y()};
} else {
digit_pos += {digit_width, 0};
frequency /= 1000; // GMMM.KKK(uuu)
for (i = 0; i < 7; i++) {
digits[6 - i] = frequency % 10;
frequency /= 10;
}
// Remove leading zeros
for (i = 0; i < 3; i++) {
if (!digits[i])
digits[i] = 16; // "Don't draw" code
else
break;
}
digit_pos = {(Coord)(240 - ((7 * digit_width) + 8) - (i * digit_width)) / 2, rect.location().y()};
}
segment_color = style().foreground;
// Draw
for (i = 0; i < 7; i++) {
digit = digits[i];
if (digit < 16) {
digit_def = segment_font[(uint8_t)digit];
for (size_t s = 0; s < 7; s++) {
if (digit_def & 1)
painter.fill_rectangle({digit_pos + segments[s].location(), segments[s].size()}, segment_color);
digit_def >>= 1;
}
}
if (i == 3) {
// Dot
painter.fill_rectangle({digit_pos + Point(34, 48), {4, 4}}, segment_color);
digit_pos += {(digit_width + 8), 0};
} else {
digit_pos += {digit_width, 0};
}
}
}
}
+1
View File
@@ -291,6 +291,7 @@ class BigFrequency : public Widget {
private:
rf::Frequency _frequency;
rf::Frequency _previous_frequency{~0LL};
static constexpr Dim digit_width = 32;
Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B