Compare commits

..

25 Commits

Author SHA1 Message Date
Totoo df3981876d Move ADSBTX to ext (#2214) 2024-08-09 23:47:08 +02:00
Totoo 05146638fc Weather size fix (#2211)
* Shrink weather size

* fix compiler warning
2024-07-29 10:46:45 +02:00
Totoo 765e3be55b SubghzD rework (#2210)
* Removed controller code

* Add Legrand

* Added Somify Keytis

* Somify

* better display
2024-07-29 07:47:50 +02:00
Totoo 9211975868 Protoview (#2206)
* ProtoView first tests

* Imp

* fix, reset
2024-07-29 07:45:56 +02:00
Erwin Ried 96a60e82bc Reshuffle the readme videos (#2208)
Does people click because thumb/title or just because the order? 🤔
2024-07-24 11:53:44 +02:00
Totoo 5d9428e568 Weather station update (#2209)
* Acurite609txc fix

* Added Kedsum

* Add auriol 5in1

* prev was: FPW_Acurite5in1, this is EmosE601x

* Remove BTN from weather
Saved flash space by creating chaos.
Fix EmosE601
2024-07-24 11:53:09 +02:00
Totoo 2fdd531fe7 Add fully randomized names to blespam (#2207)
* Add fully randomized names to blespam

* fix for all

* fix warning
2024-07-24 09:53:41 +02:00
E.T. f13756d4c7 copy ppmp to sdcard images (#2203) 2024-07-18 20:52:21 +02:00
Totoo ae6724b359 Better filter for max ic (#2201)
* fix unk

* next try
2024-07-18 09:55:11 +00:00
jLynx e11c28cf30 Added new functions (#2202) 2024-07-18 11:50:53 +02:00
Totoo b93fbad207 Add file attached in #2189 (#2199) 2024-07-18 00:11:13 +08:00
Totoo 2bedb5f09f Max17055 improvements (#2197)
* fixes

* more fixes

* more fixes

* fix

* more fixes

* fix icon updates

* fix init unk error

* simplify

* improve icon init

* code format

* Update ui_battinfo.cpp
2024-07-17 21:18:57 +12:00
Bernd Herzog 19eb6b44d5 fixed usb serial not working after reconnect (#2196)
* fixed usb serial not working after reconnect

* added restart for sd over usb disconnect

* improved usb serial fix

* fixed formatting
2024-07-17 21:17:42 +12:00
Bernd Herzog 048359fb0e added --print-memory-usage to linker parameters (#2195)
* added --print-memory-usage to linker parameters

* included standalone apps
2024-07-16 11:47:55 +02:00
jLynx ae75540d35 Max17055 (#2194)
max17055
2024-07-15 22:17:55 +02:00
Brumi-2021 9ef58b7763 updating_comments (#2191) 2024-07-08 11:11:12 +02:00
Brumi-2021 032168234a Invest limit bw ssb to 3 k (#2188)
* Adding_TX_BW_user_selection_to_the_Mic_SSB_mode

* TX_SSB_BW_adjustm_2k_3k_4k

* init_value_correction

* Comment_correction

* Leaving_only_OK_txbw_SSB_2K_3K

* Limti_SSB_TX_BW_2K_3K
2024-07-06 13:34:09 +02:00
Mihai b53b5c70d3 Radio FM and Airbands for Romania added (#2179)
* freq RO(FM and Airband)

* removed comments

* removed spaces

* Rename RO_AIRBAND.txt  to RO_AIRBAND.TXT

VS fuckup
2024-06-13 14:06:17 +08:00
Erwin Ried ee53016c6e Update README.md (#2175) 2024-06-07 11:33:45 +02:00
Totoo 2bf1116c6a New themes (#2166)
green, red themes
2024-05-28 17:51:31 +02:00
Totoo ced8012783 Theme system (#2164)
* Themes instead of Styles
* Colors changed to theme colors
* Reworked style management
* Theme settings app
* warn, menu dual set
* Added Aqua style
2024-05-27 21:02:52 +02:00
summermorningdream a8203a6372 add path class usage type debug (#2154) 2024-05-21 18:08:47 +08:00
jLynx e4d8bcb88d Updated submodule again (#2148) 2024-05-21 21:37:06 +12:00
summermorningdream db3ae29bd0 fix flash util err when no APPS dir (#2155)
* add path class usage

* fix when don't have apps dir

* clean up
2024-05-20 15:02:29 +08:00
summermorningdream 2a78c543a1 revert adding ccache tool (#2153) 2024-05-18 17:33:07 +08:00
250 changed files with 5666 additions and 1620 deletions
+2 -2
View File
@@ -54,7 +54,7 @@ jobs:
run: docker run -e VERSION_STRING=${{ steps.version_date.outputs.date }} -i -v ${{ github.workspace }}:/havoc portapack-dev
- name: Create Small SD Card ZIP - No World Map
run: |
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cd sdcard && zip -r ../sdcard-no-map.zip . && cd ..
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cp build/firmware/standalone/*/*.ppmp sdcard/APPS && cd sdcard && zip -r ../sdcard-no-map.zip . && cd ..
- name: Download world map
run: |
wget https://github.com/portapack-mayhem/mayhem-firmware/releases/download/world_map/world_map.zip
@@ -66,7 +66,7 @@ jobs:
zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip *
- name: Create SD Card ZIP
run: |
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cd sdcard && zip -r ../sdcard.zip . && cd ..
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cp build/firmware/standalone/*/*.ppmp sdcard/APPS && cd sdcard && zip -r ../sdcard.zip . && cd ..
- name: Create changelog
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+2 -2
View File
@@ -38,7 +38,7 @@ jobs:
run: docker run -e VERSION_STRING=${{ steps.version.outputs.version }} -i -v ${{ github.workspace }}:/havoc portapack-dev
- name: Create Small SD Card ZIP - No World Map
run: |
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version.outputs.version }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cd sdcard && zip -r ../sdcard-no-map.zip . && cd ..
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version.outputs.version }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cp build/firmware/standalone/*/*.ppmp sdcard/APPS && cd sdcard && zip -r ../sdcard-no-map.zip . && cd ..
- name: Download world map
run: |
wget https://github.com/portapack-mayhem/mayhem-firmware/releases/download/world_map/world_map.zip
@@ -50,7 +50,7 @@ jobs:
zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip *
- name: Create SD Card ZIP
run: |
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version.outputs.version }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cd sdcard && zip -r ../sdcard.zip . && cd ..
mkdir -p sdcard/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin sdcard/FIRMWARE/portapack-mayhem_${{ steps.version.outputs.version }}.bin && mkdir -p sdcard/APPS && cp build/firmware/application/*.ppma sdcard/APPS && cp build/firmware/standalone/*/*.ppmp sdcard/APPS && cd sdcard && zip -r ../sdcard.zip . && cd ..
- name: Create changelog
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+7 -6
View File
@@ -72,12 +72,13 @@ set(HACKRF_CPLD_XSVF_PATH ${HACKRF_PATH}/firmware/cpld/sgpio_if/${HACKRF_CPLD_XS
set(HACKRF_FIRMWARE_DFU_IMAGE ${hackrf_usb_BINARY_DIR}/${HACKRF_FIRMWARE_DFU_FILENAME})
set(HACKRF_FIRMWARE_BIN_IMAGE ${hackrf_usb_BINARY_DIR}/${HACKRF_FIRMWARE_BIN_FILENAME})
find_program(CCACHE "ccache")
if(CCACHE)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})
set(ENV{CCACHE_SLOPPINESS} pch_defines,time_macros)
endif(CCACHE)
# this seems causing some issues (ref. in discord discussions), so temporarily disabled, until figure out the pros and cons and bugs of this tool.
#find_program(CCACHE "ccache")
#if(CCACHE)
# set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE})
# set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})
# set(ENV{CCACHE_SLOPPINESS} pch_defines,time_macros)
#endif(CCACHE)
enable_testing()
add_subdirectory(firmware)
+3 -3
View File
@@ -16,9 +16,9 @@ This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmw
If you are new to *HackRF+PortaPack+Mayhem*, check these:
[<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="512">](https://grabify.link/C0J6ZR)
[<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="512">](https://grabify.link/9UZGEW)
[<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="254">](https://grabify.link/5MU2VH) [<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="254">](https://grabify.link/9UZGEW)
[<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="254">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="254">](https://grabify.link/C0J6ZR)
# Frequently Asked Questions
@@ -30,7 +30,7 @@ This repository expands upon the previous work by many people and aims to consta
:heavy_check_mark: Some individuals lean towards the [H2 with a metal enclosure](https://grabify.link/HTDXG5), but its advantages remain debated. Share your insights on our [wiki](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview).
:heavy_check_mark: Our friends at OpenSourceSDRLab give away five units every three months in our discord (check the badge on top) of their [PortaPack H2](https://grabify.link/LG0OUY), you can support them too by ordering.
:heavy_check_mark: Our friends at OpenSourceSDRLab give away five units every three months in our discord (check the badge on top) of one of their [PortaPack H2 bundle](https://grabify.link/T328XL) or [only metal case kits](https://grabify.link/LG0OUY), you can support them too by ordering.
:warning: Be cautious , *ask* the seller about compatibility with the latest releases. Look out for the description of the item, if they provide the firmware files for an older version or they have custom setup instructions, this means it might be **NOT compatible**, for example:
+4 -2
View File
@@ -177,6 +177,7 @@ set(CPPSRC
${COMMON}/utility.cpp
${COMMON}/wm8731.cpp
${COMMON}/ads1110.cpp
${COMMON}/max17055.cpp
${COMMON}/battery.cpp
${COMMON}/performance_counter.cpp
${COMMON}/bmpfile.cpp
@@ -225,6 +226,7 @@ set(CPPSRC
spectrum_color_lut.cpp
string_format.cpp
temperature_logger.cpp
theme.cpp
touch.cpp
tone_key.cpp
transmitter_model.cpp
@@ -258,7 +260,6 @@ set(CPPSRC
ui/ui_freqlist.cpp
ui/ui_tv.cpp
ui/ui_spectrum.cpp
ui/ui_styles.cpp
ui/ui_tabview.cpp
ui/ui_textentry.cpp
ui/ui_tone_key.cpp
@@ -281,7 +282,7 @@ set(CPPSRC
# apps/tpms_app.cpp
apps/ui_about_simple.cpp
apps/ui_adsb_rx.cpp
apps/ui_adsb_tx.cpp
# apps/ui_adsb_tx.cpp #moved to ext
apps/ui_aprs_rx.cpp
apps/ui_aprs_tx.cpp
apps/ui_battinfo.cpp
@@ -508,6 +509,7 @@ include_directories(. ${INCDIR})
link_directories(${LLIBDIR})
target_link_libraries(${PROJECT_NAME}.elf ${LIBS} "-L${CMAKE_CURRENT_LIST_DIR}/external")
target_link_libraries(${PROJECT_NAME}.elf -Wl,-Map=${PROJECT_NAME}.map)
target_link_libraries(${PROJECT_NAME}.elf -Wl,--print-memory-usage)
add_custom_command(
OUTPUT ${PROJECT_NAME}.bin
+10 -12
View File
@@ -39,8 +39,6 @@ namespace ui {
/* AMOptionsView *********************************************************/
static const Style& style_options_group = Styles::bg_blue;
AMOptionsView::AMOptionsView(
Rect parent_rect,
const Style* style)
@@ -297,13 +295,13 @@ void AnalogAudioView::set_options_widget(std::unique_ptr<Widget> new_widget) {
options_widget = std::move(new_widget);
} else {
// TODO: Lame hack to hide options view due to my bad paint/damage algorithm.
options_widget = std::make_unique<Rectangle>(options_view_rect, style_options_group.background);
options_widget = std::make_unique<Rectangle>(options_view_rect, Theme::getInstance()->option_active->background);
}
add_child(options_widget.get());
}
void AnalogAudioView::on_show_options_frequency() {
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, &style_options_group);
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, Theme::getInstance()->option_active);
widget->set_step(receiver_model.frequency_step());
widget->on_change_step = [this](rf::Frequency f) {
@@ -315,14 +313,14 @@ void AnalogAudioView::on_show_options_frequency() {
};
set_options_widget(std::move(widget));
field_frequency.set_style(&style_options_group);
field_frequency.set_style(Theme::getInstance()->option_active);
}
void AnalogAudioView::on_show_options_rf_gain() {
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, &style_options_group);
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, Theme::getInstance()->option_active);
set_options_widget(std::move(widget));
field_lna.set_style(&style_options_group);
field_lna.set_style(Theme::getInstance()->option_active);
}
void AnalogAudioView::on_show_options_modulation() {
@@ -331,25 +329,25 @@ void AnalogAudioView::on_show_options_modulation() {
const auto modulation = receiver_model.modulation();
switch (modulation) {
case ReceiverModel::Mode::AMAudio:
widget = std::make_unique<AMOptionsView>(options_view_rect, &style_options_group);
widget = std::make_unique<AMOptionsView>(options_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(false);
text_ctcss.hidden(true);
break;
case ReceiverModel::Mode::NarrowbandFMAudio:
widget = std::make_unique<NBFMOptionsView>(nbfm_view_rect, &style_options_group);
widget = std::make_unique<NBFMOptionsView>(nbfm_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(false);
text_ctcss.hidden(false);
break;
case ReceiverModel::Mode::WidebandFMAudio:
widget = std::make_unique<WFMOptionsView>(options_view_rect, &style_options_group);
widget = std::make_unique<WFMOptionsView>(options_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(true);
text_ctcss.hidden(true);
break;
case ReceiverModel::Mode::SpectrumAnalysis:
widget = std::make_unique<SPECOptionsView>(this, nbfm_view_rect, &style_options_group);
widget = std::make_unique<SPECOptionsView>(this, nbfm_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(false);
text_ctcss.hidden(true);
break;
@@ -360,7 +358,7 @@ void AnalogAudioView::on_show_options_modulation() {
}
set_options_widget(std::move(widget));
options_modulation.set_style(&style_options_group);
options_modulation.set_style(Theme::getInstance()->option_active);
}
void AnalogAudioView::on_frequency_step_changed(rf::Frequency f) {
@@ -29,7 +29,6 @@
#include "ui_freq_field.hpp"
#include "ui_spectrum.hpp"
#include "ui_record_view.hpp"
#include "ui_styles.hpp"
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "tone_key.hpp"
+4 -4
View File
@@ -148,13 +148,13 @@ class BLECommView : public View {
{24 * 8, 5, 6 * 8, 4}};
Labels label_send_adv{
{{0 * 8, 2 * 8}, "Send Advertisement:", Color::light_grey()}};
{{0 * 8, 2 * 8}, "Send Advertisement:", Theme::getInstance()->fg_light->foreground}};
ImageButton button_send_adv{
{21 * 8, 1 * 16, 10 * 8, 2 * 16},
&bitmap_play,
Color::green(),
Color::black()};
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
Checkbox check_log{
{24 * 8, 2 * 8},
@@ -163,7 +163,7 @@ class BLECommView : public View {
true};
Labels label_packets_sent{
{{0 * 8, 4 * 8}, "Packets Left:", Color::light_grey()}};
{{0 * 8, 4 * 8}, "Packets Left:", Theme::getInstance()->fg_light->foreground}};
Text text_packets_sent{
{13 * 8, 2 * 16, 12 * 8, 16},
+7 -7
View File
@@ -139,23 +139,23 @@ class BleRecentEntryDetailView : public View {
static constexpr uint8_t total_data_lines{5};
Labels label_mac_address{
{{0 * 8, 0 * 16}, "Mac Address:", Color::light_grey()}};
{{0 * 8, 0 * 16}, "Mac Address:", Theme::getInstance()->fg_light->foreground}};
Text text_mac_address{
{12 * 8, 0 * 16, 17 * 8, 16},
"-"};
Labels label_pdu_type{
{{0 * 8, 1 * 16}, "PDU Type:", Color::light_grey()}};
{{0 * 8, 1 * 16}, "PDU Type:", Theme::getInstance()->fg_light->foreground}};
Text text_pdu_type{
{9 * 8, 1 * 16, 17 * 8, 16},
"-"};
Labels labels{
{{0 * 8, 3 * 16}, "Len", Color::light_grey()},
{{5 * 8, 3 * 16}, "Type", Color::light_grey()},
{{10 * 8, 3 * 16}, "Value", Color::light_grey()},
{{0 * 8, 3 * 16}, "Len", Theme::getInstance()->fg_light->foreground},
{{5 * 8, 3 * 16}, "Type", Theme::getInstance()->fg_light->foreground},
{{10 * 8, 3 * 16}, "Value", Theme::getInstance()->fg_light->foreground},
};
Button button_send{
@@ -286,7 +286,7 @@ class BLERxView : public View {
{24 * 8, 5, 6 * 8, 4}};
Labels label_sort{
{{0 * 8, 3 * 8}, "Sort:", Color::light_grey()}};
{{0 * 8, 3 * 8}, "Sort:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_sort{
{5 * 8, 3 * 8},
@@ -318,7 +318,7 @@ class BLERxView : public View {
"Find"};
Labels label_found{
{{5 * 8, 6 * 8}, "Found:", Color::light_grey()}};
{{5 * 8, 6 * 8}, "Found:", Theme::getInstance()->fg_light->foreground}};
Text text_found_count{
{11 * 8, 3 * 16, 20 * 8, 16},
+8 -8
View File
@@ -218,11 +218,11 @@ class BLETxView : public View {
ImageButton button_play{
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Color::green(),
Color::black()};
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
Labels label_speed{
{{0 * 8, 6 * 8}, "Speed:", Color::light_grey()}};
{{0 * 8, 6 * 8}, "Speed:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_speed{
{7 * 8, 6 * 8},
@@ -254,7 +254,7 @@ class BLETxView : public View {
{"CONNECT_REQ", PKT_TYPE_CONNECT_REQ}}};
Labels label_marked_data{
{{0 * 8, 4 * 16}, "Marked Data:", Color::light_grey()}};
{{0 * 8, 4 * 16}, "Marked Data:", Theme::getInstance()->fg_light->foreground}};
OptionsField marked_data_sequence{
{12 * 8, 8 * 8},
@@ -264,28 +264,28 @@ class BLETxView : public View {
{"Random", 2}}};
Labels label_packet_index{
{{0 * 8, 12 * 8}, "Packet Index:", Color::light_grey()}};
{{0 * 8, 12 * 8}, "Packet Index:", Theme::getInstance()->fg_light->foreground}};
Text text_packet_index{
{13 * 8, 6 * 16, 12 * 8, 16},
"-"};
Labels label_packets_sent{
{{0 * 8, 14 * 8}, "Repeat Count:", Color::light_grey()}};
{{0 * 8, 14 * 8}, "Repeat Count:", Theme::getInstance()->fg_light->foreground}};
Text text_packets_sent{
{13 * 8, 7 * 16, 12 * 8, 16},
"-"};
Labels label_mac_address{
{{0 * 8, 16 * 8}, "Mac Address:", Color::light_grey()}};
{{0 * 8, 16 * 8}, "Mac Address:", Theme::getInstance()->fg_light->foreground}};
Text text_mac_address{
{12 * 8, 8 * 16, 20 * 8, 16},
"-"};
Labels label_data_packet{
{{0 * 8, 9 * 16}, "Packet Data:", Color::light_grey()}};
{{0 * 8, 9 * 16}, "Packet Data:", Theme::getInstance()->fg_light->foreground}};
Console console{
{0, 9 * 18, 240, 240}};
+2 -2
View File
@@ -56,8 +56,8 @@ class CaptureAppView : public View {
"rx_capture", app_settings::Mode::RX};
Labels labels{
{{0 * 8, 1 * 16}, "Rate:", Color::light_grey()},
{{11 * 8, 1 * 16}, "Format:", Color::light_grey()},
{{0 * 8, 1 * 16}, "Rate:", Theme::getInstance()->fg_light->foreground},
{{11 * 8, 1 * 16}, "Format:", Theme::getInstance()->fg_light->foreground},
};
RSSI rssi{
+13 -13
View File
@@ -163,8 +163,8 @@ void POCSAGAppView::refresh_ui() {
// Set console font style.
console.set_style(
settings_.enable_small_font
? &Styles::white_small
: &Styles::white);
? Theme::getInstance()->bg_darkest_small
: Theme::getInstance()->bg_darkest);
// Update filter button text.
std::string btn_text = "Filter Last";
@@ -260,19 +260,19 @@ void POCSAGAppView::handle_decoded(Timestamp timestamp, const std::string& prefi
static Color get_status_color(const POCSAGState& state) {
if (state.out_type == IDLE)
return Color::white();
return Theme::getInstance()->bg_darkest->foreground;
switch (state.mode) {
case STATE_CLEAR:
return Color::cyan();
return Theme::getInstance()->fg_cyan->foreground;
case STATE_HAVE_ADDRESS:
return Color::yellow();
return Theme::getInstance()->fg_yellow->foreground;
case STATE_GETTING_MSG:
return Color::green();
return Theme::getInstance()->fg_green->foreground;
}
// Shouldn't get here...
return Color::red();
return Theme::getInstance()->fg_red->foreground;
}
void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) {
@@ -294,7 +294,7 @@ void POCSAGAppView::on_packet(const POCSAGPacketMessage* message) {
last_address = 0;
} else {
// Set color before to be able to see if decode gets stuck.
image_status.set_foreground(Color::magenta());
image_status.set_foreground(Theme::getInstance()->fg_magenta->foreground);
pocsag_state.codeword_index = 0;
pocsag_state.errors = 0;
@@ -332,8 +332,8 @@ void BaudIndicator::paint(Painter& painter) {
bot = (r % 10) + '0';
}
painter.draw_char(p, Styles::white_small, top);
painter.draw_char({p.x(), p.y() + 8}, Styles::white_small, bot);
painter.draw_char(p, *Theme::getInstance()->bg_darkest_small, top);
painter.draw_char({p.x(), p.y() + 8}, *Theme::getInstance()->bg_darkest_small, bot);
}
void BitsIndicator::paint(Painter&) {
@@ -343,17 +343,17 @@ void BitsIndicator::paint(Painter&) {
int x = p.x() + (i / height);
int y = p.y() + (i % height);
display.draw_pixel({x, y}, is_set ? Color::white() : Color::black());
display.draw_pixel({x, y}, is_set ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background);
}
}
void FrameIndicator::paint(Painter& painter) {
auto p = screen_pos();
painter.draw_rectangle({p, {2, height}}, has_sync_ ? Color::green() : Color::grey());
painter.draw_rectangle({p, {2, height}}, has_sync_ ? Theme::getInstance()->fg_green->foreground : Theme::getInstance()->bg_medium->background);
for (size_t i = 0; i < height; ++i) {
auto p2 = p + Point{2, 15 - (int)i};
painter.draw_hline(p2, 2, i < frame_count_ ? Color::white() : Color::black());
painter.draw_hline(p2, 2, i < frame_count_ ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background);
}
}
+4 -5
View File
@@ -27,7 +27,6 @@
#include "ui_freq_field.hpp"
#include "ui_receiver.hpp"
#include "ui_rssi.hpp"
#include "ui_styles.hpp"
#include "app_settings.hpp"
#include "log_file.hpp"
@@ -141,8 +140,8 @@ class POCSAGSettingsView : public View {
POCSAGSettings& settings_;
Labels labels{
{{2 * 8, 12 * 16}, "Filter Mode:", Color::light_grey()},
{{2 * 8, 13 * 16}, "Filter Addr:", Color::light_grey()},
{{2 * 8, 12 * 16}, "Filter Mode:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 13 * 16}, "Filter Addr:", Theme::getInstance()->fg_light->foreground},
};
Checkbox check_log{
@@ -265,8 +264,8 @@ class POCSAGAppView : public View {
Image image_status{
{0 * 8 + 4, 1 * 16 + 2, 16, 16},
&bitmap_icon_pocsag,
Color::white(),
Color::black()};
Theme::getInstance()->bg_darkest->foreground,
Theme::getInstance()->bg_darkest->background};
Text text_packet_count{
{3 * 8, 1 * 16 + 2, 5 * 8, 16},
+2 -2
View File
@@ -112,8 +112,8 @@ class ReplayAppView : public View {
ImageButton button_play{
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Color::green(),
Color::black()};
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
spectrum::WaterfallView waterfall{};
+1 -1
View File
@@ -214,7 +214,7 @@ void SoundBoardView::refresh_list() {
for (size_t n = 0; n < file_list.size(); n++) {
menu_view.add_item({file_list[n].string().substr(0, 30),
ui::Color::dark_magenta(),
ui::Theme::getInstance()->fg_magenta->foreground,
nullptr,
[this](KeyEvent) {
on_select_entry();
+2 -2
View File
@@ -92,8 +92,8 @@ class SoundBoardView : public View {
void on_select_entry();
Labels labels{
{{24 * 8, 180}, "Vol:", Color::light_grey()},
{{0, 180}, "Key:", Color::light_grey()}};
{{24 * 8, 180}, "Vol:", Theme::getInstance()->fg_light->foreground},
{{0, 180}, "Key:", Theme::getInstance()->fg_light->foreground}};
Button button_next_page{
{30 * 7, 25 * 8, 10 * 3, 2 * 14},
+2 -2
View File
@@ -71,7 +71,7 @@ void CreditsWidget::new_row(
void CreditsWidget::clear() {
display.fill_rectangle(
screen_rect(),
Color::black());
Theme::getInstance()->bg_darkest->background);
}
void AboutView::update() {
@@ -109,7 +109,7 @@ void AboutView::update() {
const size_t start = (glyph.size().width() / 8) * render_line;
for (Dim c = 0; c < glyph.size().width(); c++) {
const auto pixel = glyph.pixels()[start + (c >> 3)] & (1U << (c & 0x7));
pixel_row[start_pos + i + c] = pixel ? Color::white() : Color::black();
pixel_row[start_pos + i + c] = pixel ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background;
}
const auto advance = glyph.advance();
@@ -65,13 +65,13 @@ AboutView::AboutView(NavigationView& nav) {
if (authors_line[0] == '#') {
menu_view.add_item(
{authors_line.substr(1, authors_line.size() - 1),
ui::Color::yellow(),
ui::Theme::getInstance()->fg_yellow->foreground,
nullptr,
nullptr});
} else {
menu_view.add_item(
{authors_line,
ui::Color::white(),
Theme::getInstance()->bg_darkest->foreground,
nullptr,
nullptr});
}
+3 -3
View File
@@ -57,15 +57,15 @@ void RecentEntriesTable<AircraftRecentEntries>::draw(
case ADSBAgeState::Invalid:
case ADSBAgeState::Current:
entry_string = "";
target_color = Color::green();
target_color = Theme::getInstance()->fg_green->foreground;
break;
case ADSBAgeState::Recent:
entry_string = STR_COLOR_LIGHT_GREY;
target_color = Color::light_grey();
target_color = Theme::getInstance()->fg_light->foreground;
break;
default:
entry_string = STR_COLOR_DARK_GREY;
target_color = Color::grey();
target_color = Theme::getInstance()->fg_medium->foreground;
};
entry_string +=
+19 -19
View File
@@ -205,15 +205,15 @@ class ADSBRxAircraftDetailsView : public View {
private:
Labels labels{
{{0 * 8, 1 * 16}, "ICAO:", Color::light_grey()},
{{0 * 8, 2 * 16}, "Registration:", Color::light_grey()},
{{0 * 8, 3 * 16}, "Manufacturer:", Color::light_grey()},
{{0 * 8, 5 * 16}, "Model:", Color::light_grey()},
{{0 * 8, 7 * 16}, "Type:", Color::light_grey()},
{{0 * 8, 8 * 16}, "Number of engines:", Color::light_grey()},
{{0 * 8, 9 * 16}, "Engine type:", Color::light_grey()},
{{0 * 8, 11 * 16}, "Owner:", Color::light_grey()},
{{0 * 8, 13 * 16}, "Operator:", Color::light_grey()}};
{{0 * 8, 1 * 16}, "ICAO:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Registration:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Manufacturer:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Model:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "Type:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Number of engines:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 9 * 16}, "Engine type:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 11 * 16}, "Owner:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, "Operator:", Theme::getInstance()->fg_light->foreground}};
Text text_icao_address{
{5 * 8, 1 * 16, 6 * 8, 16},
@@ -289,13 +289,13 @@ class ADSBRxDetailsView : public View {
bool airline_checked{false};
Labels labels{
{{0 * 8, 1 * 16}, "ICAO:", Color::light_grey()},
{{13 * 8, 1 * 16}, "Callsign:", Color::light_grey()},
{{0 * 8, 2 * 16}, "Last seen:", Color::light_grey()},
{{0 * 8, 3 * 16}, "Airline:", Color::light_grey()},
{{0 * 8, 5 * 16}, "Country:", Color::light_grey()},
{{0 * 8, 13 * 16}, "Even position frame:", Color::light_grey()},
{{0 * 8, 15 * 16}, "Odd position frame:", Color::light_grey()}};
{{0 * 8, 1 * 16}, "ICAO:", Theme::getInstance()->fg_light->foreground},
{{13 * 8, 1 * 16}, "Callsign:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Last seen:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Airline:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Country:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, "Even position frame:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 15 * 16}, "Odd position frame:", Theme::getInstance()->fg_light->foreground}};
Text text_icao_address{
{5 * 8, 1 * 16, 6 * 8, 16},
@@ -414,7 +414,7 @@ class ADSBRxView : public View {
ADSBRxDetailsView* details_view{nullptr};
Labels labels{
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Color::light_grey()}};
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Theme::getInstance()->fg_light->foreground}};
LNAGainField field_lna{
{4 * 8, 0 * 16}};
@@ -431,12 +431,12 @@ class ADSBRxView : public View {
ActivityDot status_frame{
{27 * 8 + 2, 5, 2, 2},
Color::white(),
Theme::getInstance()->bg_darkest->foreground,
};
ActivityDot status_good_frame{
{27 * 8 + 2, 9, 2, 2},
Color::green(),
Theme::getInstance()->fg_green->foreground,
};
AudioVolumeField field_volume{
+1 -1
View File
@@ -46,7 +46,7 @@ void RecentEntriesTable<APRSRecentEntries>::draw(
Color target_color;
// auto entry_age = entry.age;
target_color = Color::green();
target_color = Theme::getInstance()->fg_green->foreground;
std::string entry_string = "";
+2 -2
View File
@@ -261,8 +261,8 @@ class APRSRXView : public View {
APRSTableView view_table{nav_, view_rect};
TabView tab_view{
{"Stream", Color::cyan(), &view_stream},
{"List", Color::yellow(), &view_table}};
{"Stream", Theme::getInstance()->fg_cyan->foreground, &view_stream},
{"List", Theme::getInstance()->fg_yellow->foreground, &view_table}};
MessageHandlerRegistration message_handler_packet{
Message::ID::APRSPacket,
+3 -3
View File
@@ -61,9 +61,9 @@ class APRSTXView : public View {
void on_tx_progress(const uint32_t progress, const bool done);
Labels labels{
{{0 * 8, 1 * 16}, "Source: SSID:", Color::light_grey()}, // 6 alphanum + SSID
{{0 * 8, 2 * 16}, " Dest.: SSID:", Color::light_grey()},
{{0 * 8, 4 * 16}, "Info field:", Color::light_grey()},
{{0 * 8, 1 * 16}, "Source: SSID:", Theme::getInstance()->fg_light->foreground}, // 6 alphanum + SSID
{{0 * 8, 2 * 16}, " Dest.: SSID:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 4 * 16}, "Info field:", Theme::getInstance()->fg_light->foreground},
};
SymField sym_source{
+10 -13
View File
@@ -24,14 +24,13 @@
#include "event_m0.hpp"
#include "portapack.hpp"
#include "battery.hpp"
#include <cstring>
using namespace portapack;
namespace ui {
bool BattinfoView::needRun = true;
void BattinfoView::focus() {
button_exit.focus();
}
@@ -46,7 +45,6 @@ void BattinfoView::on_timer() {
void BattinfoView::update_result() {
if (!battery::BatteryManagement::isDetected()) {
// todo show no batt management
text_percent.set("UNKNOWN");
text_voltage.set("UNKNOWN");
text_current.set("-");
@@ -54,24 +52,25 @@ void BattinfoView::update_result() {
return;
}
bool uichg = false;
battery::BatteryManagement::getBatteryInfo(percent, voltage, current, isCharging);
uint8_t valid_mask = 0;
battery::BatteryManagement::getBatteryInfo(valid_mask, percent, voltage, current);
// update text fields
if (percent <= 100)
if (percent <= 100 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE)
text_percent.set(to_string_dec_uint(percent) + " %");
else
text_percent.set("UNKNOWN");
if (voltage > 1) {
if (voltage > 1 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE) {
text_voltage.set(to_string_decimal(voltage / 1000.0, 3) + " V");
} else {
text_voltage.set("UNKNOWN");
}
if (current != 0) {
if ((valid_mask & battery::BatteryManagement::BATT_VALID_CURRENT) == battery::BatteryManagement::BATT_VALID_CURRENT) {
if (labels_opt.hidden()) uichg = true;
labels_opt.hidden(false);
text_current.hidden(false);
text_charge.hidden(false);
text_current.set(to_string_dec_int(current) + " mA");
text_charge.set(isCharging ? "charge" : "discharge");
text_charge.set(current >= 0 ? "Charging" : "Discharging");
labels_opt.hidden(false);
} else {
if (!labels_opt.hidden()) uichg = true;
@@ -81,7 +80,7 @@ void BattinfoView::update_result() {
}
if (uichg) set_dirty();
// to update status bar too, send message in behalf of batt manager
BatteryStateMessage msg{percent, isCharging, voltage};
BatteryStateMessage msg{valid_mask, percent, current >= 0, voltage};
EventDispatcher::send_message(msg);
}
@@ -100,13 +99,12 @@ BattinfoView::BattinfoView(NavigationView& nav)
};
update_result();
needRun = true;
thread = chThdCreateFromHeap(NULL, 512, NORMALPRIO + 10, BattinfoView::static_fn, this);
if (thread == nullptr) thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, BattinfoView::static_fn, this);
}
msg_t BattinfoView::static_fn(void* arg) {
auto obj = static_cast<BattinfoView*>(arg);
while (needRun) {
while (!chThdShouldTerminate()) {
chThdSleepMilliseconds(16);
obj->on_timer();
}
@@ -114,7 +112,6 @@ msg_t BattinfoView::static_fn(void* arg) {
}
BattinfoView::~BattinfoView() {
needRun = false;
if (thread) {
chThdTerminate(thread);
chThdWait(thread);
+4 -6
View File
@@ -50,15 +50,14 @@ class BattinfoView : public View {
uint8_t percent = 0;
uint16_t voltage = 0;
int32_t current = 0;
bool isCharging = false;
Labels labels{
{{2 * 8, 1 * 16}, "Percent:", Color::light_grey()},
{{2 * 8, 2 * 16}, "Voltage:", Color::light_grey()}};
{{2 * 8, 1 * 16}, "Percent:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 2 * 16}, "Voltage:", Theme::getInstance()->fg_light->foreground}};
Labels labels_opt{
{{2 * 8, 3 * 16}, "Current:", Color::light_grey()},
{{2 * 8, 4 * 16}, "Charge:", Color::light_grey()}};
{{2 * 8, 3 * 16}, "Current:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 4 * 16}, "Charge:", Theme::getInstance()->fg_light->foreground}};
Text text_percent{
{13 * 8, 1 * 16, 10 * 16, 16},
@@ -77,7 +76,6 @@ class BattinfoView : public View {
{72, 17 * 16, 96, 32},
"Back"};
static msg_t static_fn(void* arg);
static bool needRun;
Thread* thread{nullptr};
};
+12 -12
View File
@@ -50,12 +50,12 @@ class XylosView : public View {
private:
Labels labels{
{{8 * 8, 1 * 8}, "Header:", Color::light_grey()},
{{4 * 8, 3 * 8}, "City code:", Color::light_grey()},
{{7 * 8, 5 * 8}, "Family:", Color::light_grey()},
{{2 * 8, 7 * 8 + 2}, "Subfamily:", Color::light_grey()},
{{2 * 8, 11 * 8}, "Receiver ID:", Color::light_grey()},
{{2 * 8, 14 * 8}, "Relay:", Color::light_grey()}};
{{8 * 8, 1 * 8}, "Header:", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 3 * 8}, "City code:", Theme::getInstance()->fg_light->foreground},
{{7 * 8, 5 * 8}, "Family:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 8 + 2}, "Subfamily:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 11 * 8}, "Receiver ID:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 14 * 8}, "Relay:", Theme::getInstance()->fg_light->foreground}};
NumberField field_header_a{
{16 * 8, 1 * 8},
@@ -130,9 +130,9 @@ class EPARView : public View {
private:
Labels labels{
{{4 * 8, 1 * 8}, "City code:", Color::light_grey()},
{{8 * 8, 3 * 8}, "Group:", Color::light_grey()},
{{8 * 8, 7 * 8}, "Relay:", Color::light_grey()}};
{{4 * 8, 1 * 8}, "City code:", Theme::getInstance()->fg_light->foreground},
{{8 * 8, 3 * 8}, "Group:", Theme::getInstance()->fg_light->foreground},
{{8 * 8, 7 * 8}, "Relay:", Theme::getInstance()->fg_light->foreground}};
NumberField field_city{
{16 * 8, 1 * 8},
@@ -195,11 +195,11 @@ class BHTView : public View {
EPARView view_EPAR{view_rect};
TabView tab_view{
{"Xylos", Color::cyan(), &view_xylos},
{"EPAR", Color::green(), &view_EPAR}};
{"Xylos", Theme::getInstance()->fg_cyan->foreground, &view_xylos},
{"EPAR", Theme::getInstance()->fg_green->foreground, &view_EPAR}};
Labels labels{
{{29 * 8, 14 * 16 + 4}, "s", Color::light_grey()}};
{{29 * 8, 14 * 16 + 4}, "s", Theme::getInstance()->fg_light->foreground}};
Checkbox checkbox_scan{
{1 * 8, 25 * 8},
@@ -25,7 +25,6 @@
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_painter.hpp"
#include "ui_styles.hpp"
#include "ui_widget.hpp"
#include "file.hpp"
#include "ui_bmpview.hpp"
+39 -31
View File
@@ -34,7 +34,6 @@
#include "ui_sd_card_debug.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "ui_styles.hpp"
#include "ui_painter.hpp"
#include "ui_external_items_menu_loader.hpp"
@@ -80,7 +79,7 @@ void TemperatureWidget::paint(Painter& painter) {
const auto rect = screen_rect();
const Color color_background{0, 0, 64};
const Color color_foreground = Color::green();
const Color color_foreground = Theme::getInstance()->fg_green->foreground;
const Color color_reticle{128, 128, 128};
const auto graph_width = static_cast<int>(logger.capacity()) * bar_width;
@@ -226,6 +225,8 @@ uint32_t RegistersWidget::reg_read(const uint32_t register_number) {
return radio::debug::second_if::register_read(register_number);
case CT_SI5351:
return portapack::clock_generator.read_register(register_number);
case CT_BATTERY:
return battery::BatteryManagement::read_register(register_number);
case CT_AUDIO:
return audio::debug::reg_read(register_number);
}
@@ -247,6 +248,9 @@ void RegistersWidget::reg_write(const uint32_t register_number, const uint32_t v
case CT_SI5351:
portapack::clock_generator.write_register(register_number, value);
break;
case CT_BATTERY:
battery::BatteryManagement::write_register(register_number, value);
break;
case CT_AUDIO:
audio::debug::reg_write(register_number, value);
break;
@@ -292,7 +296,7 @@ RegistersView::RegistersView(
const auto value = registers_widget.reg_read(0);
field_write_data_val.set_value(value);
button_write.set_style(&Styles::red);
button_write.set_style(Theme::getInstance()->fg_red);
button_write.on_select = [this](Button&) {
this->registers_widget.reg_write(field_write_reg_num.to_integer(), field_write_data_val.to_integer());
this->registers_widget.update();
@@ -315,7 +319,7 @@ bool RegistersView::on_encoder(const EncoderEvent delta) {
void ControlsSwitchesWidget::on_show() {
display.fill_rectangle(
screen_rect(),
Color::black());
Theme::getInstance()->bg_darkest->background);
}
bool ControlsSwitchesWidget::on_key(const KeyEvent key) {
@@ -345,11 +349,11 @@ void ControlsSwitchesWidget::paint(Painter& painter) {
}};
for (const auto r : button_rects) {
painter.fill_rectangle(r + pos, Color::blue());
painter.fill_rectangle(r + pos, Theme::getInstance()->fg_blue->foreground);
}
if (get_touch_frame().touch)
painter.fill_rectangle(button_rects[8] + pos, Color::yellow());
painter.fill_rectangle(button_rects[8] + pos, Theme::getInstance()->fg_yellow->foreground);
const std::array<Rect, 8> raw_rects{{
{64 + 1, 32 + 1, 16 - 2, 16 - 2}, // Right
@@ -365,7 +369,7 @@ void ControlsSwitchesWidget::paint(Painter& painter) {
auto switches_raw = control::debug::switches();
for (const auto r : raw_rects) {
if (switches_raw & 1)
painter.fill_rectangle(r + pos, Color::yellow());
painter.fill_rectangle(r + pos, Theme::getInstance()->fg_yellow->foreground);
switches_raw >>= 1;
}
@@ -382,7 +386,7 @@ void ControlsSwitchesWidget::paint(Painter& painter) {
auto switches_debounced = get_switches_state().to_ulong();
for (const auto r : debounced_rects) {
if (switches_debounced & 1)
painter.fill_rectangle(r + pos, Color::green());
painter.fill_rectangle(r + pos, Theme::getInstance()->fg_green->foreground);
switches_debounced >>= 1;
}
@@ -399,7 +403,7 @@ void ControlsSwitchesWidget::paint(Painter& painter) {
auto switches_event = key_event_mask;
for (const auto r : events_rects) {
if (switches_event & 1)
painter.fill_rectangle(r + pos, Color::red());
painter.fill_rectangle(r + pos, Theme::getInstance()->fg_red->foreground);
switches_event >>= 1;
}
@@ -407,12 +411,12 @@ void ControlsSwitchesWidget::paint(Painter& painter) {
switches_event = long_press_key_event_mask;
for (const auto r : events_rects) {
if (switches_event & 1)
painter.fill_rectangle(r + pos, Color::cyan());
painter.fill_rectangle(r + pos, Theme::getInstance()->fg_cyan->foreground);
switches_event >>= 1;
}
painter.draw_string({5 * 8, 12 * 16}, Styles::light_grey, to_string_dec_int(last_delta, 3));
painter.draw_string({5 * 8, 12 * 16}, *Theme::getInstance()->fg_light, to_string_dec_int(last_delta, 3));
}
void ControlsSwitchesWidget::on_frame_sync() {
@@ -455,11 +459,15 @@ void DebugPeripheralsMenuView::on_populate() {
const char* max283x = hackrf_r9 ? "MAX2839" : "MAX2837";
const char* si5351x = hackrf_r9 ? "Si5351A" : "Si5351C";
add_items({
{"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }},
{max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, max283x]() { nav_.push<RegistersView>(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }},
{si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push<RegistersView>(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }},
{audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }},
{"RFFC5072", Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }},
{max283x, Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this, max283x]() { nav_.push<RegistersView>(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }},
{si5351x, Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push<RegistersView>(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }},
{audio::debug::codec_name(), Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }},
});
if (battery::BatteryManagement::detectedModule() == battery::BatteryManagement::BatteryModules::BATT_MAX17055) {
add_item(
{"MAX17055", Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>("MAX17055", RegistersWidgetConfig{CT_BATTERY, 256, 16, 16}); }});
}
set_max_rows(2); // allow wider buttons
}
@@ -486,21 +494,21 @@ DebugMenuView::DebugMenuView(NavigationView& nav)
void DebugMenuView::on_populate() {
if (portapack::persistent_memory::show_gui_return_icon()) {
add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}});
add_items({{"..", ui::Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}});
}
add_items({
{"Buttons Test", ui::Color::dark_cyan(), &bitmap_icon_controls, [this]() { nav_.push<DebugControlsView>(); }},
{"Debug Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { portapack::persistent_memory::debug_dump(); }},
{"M0 Stack Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { stack_dump(); }},
{"Memory Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryDumpView>(); }},
//{"Memory Usage", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryView>(); }},
{"Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [this]() { nav_.push<DebugPeripheralsMenuView>(); }},
{"Pers. Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push<DebugPmemView>(); }},
//{ "Radio State", ui::Color::white(), nullptr, [this](){ nav_.push<NotImplementedView>(); } },
{"Reboot", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<DebugReboot>(); }},
{"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [this]() { nav_.push<SDCardDebugView>(); }},
{"Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [this]() { nav_.push<TemperatureView>(); }},
{"Touch Test", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push<DebugScreenTest>(); }},
{"Buttons Test", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_controls, [this]() { nav_.push<DebugControlsView>(); }},
{"Debug Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { portapack::persistent_memory::debug_dump(); }},
{"M0 Stack Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { stack_dump(); }},
{"Memory Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryDumpView>(); }},
//{"Memory Usage", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryView>(); }},
{"Peripherals", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals, [this]() { nav_.push<DebugPeripheralsMenuView>(); }},
{"Pers. Memory", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugPmemView>(); }},
//{ "Radio State", ui::Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ nav_.push<NotImplementedView>(); } },
{"SD Card", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_sdcard, [this]() { nav_.push<SDCardDebugView>(); }},
{"Temperature", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_temperature, [this]() { nav_.push<TemperatureView>(); }},
{"Touch Test", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_notepad, [this]() { nav_.push<DebugScreenTest>(); }},
{"Reboot", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_setup, [this]() { nav_.push<DebugReboot>(); }},
});
for (auto const& gridItem : ExternalItemsMenuLoader::load_external_items(app_location_t::DEBUG, nav_)) {
@@ -535,7 +543,7 @@ DebugMemoryDumpView::DebugMemoryDumpView(NavigationView& nav) {
field_data_value.set_dirty();
};
button_write.set_style(&Styles::red);
button_write.set_style(Theme::getInstance()->fg_red);
button_write.on_select = [this](Button&) {
*(uint32_t*)field_rw_address.to_integer() = (uint32_t)field_data_value.to_integer();
};
@@ -618,8 +626,8 @@ bool DebugScreenTest::on_touch(const TouchEvent event) {
}
void DebugScreenTest::paint(Painter& painter) {
painter.fill_rectangle({0, 16, screen_width, screen_height - 16}, Color::white());
painter.draw_string({10 * 8, screen_height / 2}, Styles::white, "Use Stylus");
painter.fill_rectangle({0, 16, screen_width, screen_height - 16}, Theme::getInstance()->bg_darkest->foreground);
painter.draw_string({10 * 8, screen_height / 2}, *Theme::getInstance()->bg_darkest, "Use Stylus");
pen_color = std::rand();
}
+12 -11
View File
@@ -139,6 +139,7 @@ typedef enum {
CT_MAX283X,
CT_SI5351,
CT_AUDIO,
CT_BATTERY,
} chip_type_t;
struct RegistersWidgetConfig {
@@ -233,8 +234,8 @@ class RegistersView : public View {
"Write"};
Labels labels{
{{1 * 8, 248}, "Reg:", Color::light_grey()},
{{8 * 8, 248}, "Data:", Color::light_grey()}};
{{1 * 8, 248}, "Reg:", Theme::getInstance()->fg_light->foreground},
{{8 * 8, 248}, "Data:", Theme::getInstance()->fg_light->foreground}};
SymField field_write_reg_num{
{5 * 8, 248},
@@ -288,9 +289,9 @@ class DebugControlsView : public View {
private:
Labels labels{
{{8 * 8, 1 * 16}, "Controls State", Color::white()},
{{0 * 8, 11 * 16}, "Dial:", Color::grey()},
{{0 * 8, 14 * 16}, "Long-Press Mode:", Color::grey()}};
{{8 * 8, 1 * 16}, "Controls State", Theme::getInstance()->bg_darkest->foreground},
{{0 * 8, 11 * 16}, "Dial:", Theme::getInstance()->fg_medium->foreground},
{{0 * 8, 14 * 16}, "Long-Press Mode:", Theme::getInstance()->fg_medium->foreground}};
ControlsSwitchesWidget switches_widget{
{80, 80, 80, 112},
@@ -333,12 +334,12 @@ class DebugMemoryDumpView : public View {
"Done"};
Labels labels{
{{5 * 8, 1 * 16}, "Dump Range to File", Color::yellow()},
{{0 * 8, 2 * 16}, "Starting Address: 0x", Color::light_grey()},
{{0 * 8, 3 * 16}, "Byte Count: 0x", Color::light_grey()},
{{3 * 8, 8 * 16}, "Read/Write Single Word", Color::yellow()},
{{0 * 8, 9 * 16}, "Memory Address: 0x", Color::light_grey()},
{{0 * 8, 10 * 16}, "Data Value: 0x", Color::light_grey()}};
{{5 * 8, 1 * 16}, "Dump Range to File", Theme::getInstance()->fg_yellow->foreground},
{{0 * 8, 2 * 16}, "Starting Address: 0x", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Byte Count: 0x", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 8 * 16}, "Read/Write Single Word", Theme::getInstance()->fg_yellow->foreground},
{{0 * 8, 9 * 16}, "Memory Address: 0x", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "Data Value: 0x", Theme::getInstance()->fg_light->foreground}};
SymField field_starting_address{
{20 * 8, 2 * 16},
+10 -10
View File
@@ -74,27 +74,27 @@ void DfuMenu::paint(Painter& painter) {
painter.fill_rectangle(
{{6 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
{15 * CHARACTER_WIDTH + margin * 2, lines * LINE_HEIGHT + margin * 2}},
ui::Color::black());
Theme::getInstance()->bg_darkest->background);
painter.fill_rectangle(
{{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{21 * CHARACTER_WIDTH + margin, 3 * LINE_HEIGHT - margin},
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin - 8},
{17 * CHARACTER_WIDTH + margin * 2, 8}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{5 * CHARACTER_WIDTH - margin, (lines + 3) * LINE_HEIGHT + margin},
{17 * CHARACTER_WIDTH + margin * 2, 8}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
}
DfuMenu2::DfuMenu2(NavigationView& nav)
@@ -133,27 +133,27 @@ void DfuMenu2::paint(Painter& painter) {
painter.fill_rectangle(
{{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
{19 * CHARACTER_WIDTH + margin * 2, lines * LINE_HEIGHT + margin * 2}},
ui::Color::black());
Theme::getInstance()->bg_darkest->background);
painter.fill_rectangle(
{{4 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{24 * CHARACTER_WIDTH + margin, 3 * LINE_HEIGHT - margin},
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{4 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin - 8},
{21 * CHARACTER_WIDTH + margin * 2, 8}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
painter.fill_rectangle(
{{4 * CHARACTER_WIDTH - margin, (lines + 3) * LINE_HEIGHT + margin},
{21 * CHARACTER_WIDTH + margin * 2, 8}},
ui::Color::dark_cyan());
ui::Theme::getInstance()->fg_darkcyan->foreground);
}
} /* namespace ui */
+22 -22
View File
@@ -49,18 +49,18 @@ class DfuMenu : public View {
Text text_head{{6 * CHARACTER_WIDTH, 3 * LINE_HEIGHT, 11 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, "Performance"};
Labels labels{
{{6 * CHARACTER_WIDTH, 5 * LINE_HEIGHT}, "M0 core:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 6 * LINE_HEIGHT}, "M0 heap:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 7 * LINE_HEIGHT}, "M0 frags:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 8 * LINE_HEIGHT}, "M0 stack:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "M0 cpu %:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "M4 heap:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "M4 stack:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 12 * LINE_HEIGHT}, "M4 cpu %:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 13 * LINE_HEIGHT}, "M4 miss:", Color::dark_cyan()},
{{6 * CHARACTER_WIDTH, 14 * LINE_HEIGHT}, "Uptime:", Color::dark_cyan()}};
{{6 * CHARACTER_WIDTH, 5 * LINE_HEIGHT}, "M0 core:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 6 * LINE_HEIGHT}, "M0 heap:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 7 * LINE_HEIGHT}, "M0 frags:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 8 * LINE_HEIGHT}, "M0 stack:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "M0 cpu %:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "M4 heap:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "M4 stack:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 12 * LINE_HEIGHT}, "M4 cpu %:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 13 * LINE_HEIGHT}, "M4 miss:", Theme::getInstance()->fg_darkcyan->foreground},
{{6 * CHARACTER_WIDTH, 14 * LINE_HEIGHT}, "Uptime:", Theme::getInstance()->fg_darkcyan->foreground}};
Labels voltage_label{{{6 * CHARACTER_WIDTH, 15 * LINE_HEIGHT}, "Voltage:", Color::dark_cyan()}};
Labels voltage_label{{{6 * CHARACTER_WIDTH, 15 * LINE_HEIGHT}, "Voltage:", Theme::getInstance()->fg_darkcyan->foreground}};
Text text_info_line_1{{15 * CHARACTER_WIDTH, 5 * LINE_HEIGHT, 6 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
Text text_info_line_2{{15 * CHARACTER_WIDTH, 6 * LINE_HEIGHT, 6 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
@@ -88,17 +88,17 @@ class DfuMenu2 : public View {
Text text_head{{6 * CHARACTER_WIDTH, 3 * LINE_HEIGHT, 14 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, "Radio Settings"};
Labels labels{
{{5 * CHARACTER_WIDTH, 5 * LINE_HEIGHT}, "RX Freq:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 6 * LINE_HEIGHT}, "RX BW:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 7 * LINE_HEIGHT}, "RX SampR:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 8 * LINE_HEIGHT}, "RX Satu%:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "Modulatn:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "AM cfg:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "NBFM cfg:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 12 * LINE_HEIGHT}, "WFM cfg:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 13 * LINE_HEIGHT}, "TX Freq:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 14 * LINE_HEIGHT}, "TX BW:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 15 * LINE_HEIGHT}, "TX SampR:", Color::dark_cyan()},
{{5 * CHARACTER_WIDTH, 5 * LINE_HEIGHT}, "RX Freq:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 6 * LINE_HEIGHT}, "RX BW:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 7 * LINE_HEIGHT}, "RX SampR:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 8 * LINE_HEIGHT}, "RX Satu%:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "Modulatn:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "AM cfg:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "NBFM cfg:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 12 * LINE_HEIGHT}, "WFM cfg:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 13 * LINE_HEIGHT}, "TX Freq:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 14 * LINE_HEIGHT}, "TX BW:", Theme::getInstance()->fg_darkcyan->foreground},
{{5 * CHARACTER_WIDTH, 15 * LINE_HEIGHT}, "TX SampR:", Theme::getInstance()->fg_darkcyan->foreground},
};
Text text_info_line_1{{14 * CHARACTER_WIDTH, 5 * LINE_HEIGHT, 10 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
+16 -16
View File
@@ -64,16 +64,16 @@ class EncodersConfigView : public View {
void on_type_change(size_t index);
Labels labels{
{{1 * 8, 0}, "Type:", Color::light_grey()},
{{17 * 8, 0}, "Repeat:", Color::light_grey()},
{{1 * 8, 2 * 8}, "Clk:", Color::light_grey()},
{{10 * 8, 2 * 8}, "kHz", Color::light_grey()},
{{17 * 8, 2 * 8}, "Step:", Color::light_grey()},
{{1 * 8, 4 * 8}, "Frame:", Color::light_grey()},
{{13 * 8, 4 * 8}, "us", Color::light_grey()},
{{17 * 8, 4 * 8}, "Step:", Color::light_grey()},
{{2 * 8, 7 * 8}, "Symbols:", Color::light_grey()},
{{1 * 8, 14 * 8}, "Waveform:", Color::light_grey()}};
{{1 * 8, 0}, "Type:", Theme::getInstance()->fg_light->foreground},
{{17 * 8, 0}, "Repeat:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 8}, "Clk:", Theme::getInstance()->fg_light->foreground},
{{10 * 8, 2 * 8}, "kHz", Theme::getInstance()->fg_light->foreground},
{{17 * 8, 2 * 8}, "Step:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 4 * 8}, "Frame:", Theme::getInstance()->fg_light->foreground},
{{13 * 8, 4 * 8}, "us", Theme::getInstance()->fg_light->foreground},
{{17 * 8, 4 * 8}, "Step:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 8}, "Symbols:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 14 * 8}, "Waveform:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_enctype{// Options are loaded at runtime
{6 * 8, 0},
@@ -128,7 +128,7 @@ class EncodersConfigView : public View {
0,
0,
true,
Color::yellow()};
Theme::getInstance()->fg_yellow->foreground};
};
class EncodersScanView : public View {
@@ -160,9 +160,9 @@ class EncodersScanView : public View {
private:
Labels labels{
{{1 * 8, 0 * 8}, "Length:", Color::light_grey()},
{{1 * 8, 2 * 8}, "Bit length:", Color::light_grey()},
{{16 * 8, 2 * 8}, "us", Color::light_grey()},
{{1 * 8, 0 * 8}, "Length:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 8}, "Bit length:", Theme::getInstance()->fg_light->foreground},
{{16 * 8, 2 * 8}, "us", Theme::getInstance()->fg_light->foreground},
};
};
@@ -206,8 +206,8 @@ class EncodersView : public View {
EncodersScanView view_scan{nav_, view_rect};
TabView tab_view{
{"Config", Color::cyan(), &view_config},
{"de Bruijn", Color::green(), &view_scan},
{"Config", Theme::getInstance()->fg_cyan->foreground, &view_config},
{"de Bruijn", Theme::getInstance()->fg_green->foreground, &view_scan},
};
Text text_status{
+4 -4
View File
@@ -389,7 +389,7 @@ void FileManBaseView::refresh_list() {
menu_view.add_item(
{entry_name.substr(0, max_filename_length) + std::string(21 - entry_name.length(), ' ') + size_str,
ui::Color::yellow(),
Theme::getInstance()->fg_yellow->foreground,
&bitmap_icon_dir,
[this](KeyEvent key) {
if (on_select_entry)
@@ -747,10 +747,10 @@ FileManagerView::FileManagerView(
menu_view.on_highlight = [this]() {
if (menu_view.highlighted_index() >= max_items_loaded - 1) { // todo check this if correct
text_date.set_style(&Styles::red);
text_date.set_style(Theme::getInstance()->fg_red);
text_date.set("Too many files!");
} else {
text_date.set_style(&Styles::grey);
text_date.set_style(Theme::getInstance()->fg_medium);
if (selected_is_valid())
text_date.set((is_directory(get_selected_full_path()) ? "Created " : "Modified ") + to_string_FAT_timestamp(file_created_date(get_selected_full_path())));
else
@@ -858,7 +858,7 @@ FileManagerView::FileManagerView(
button_show_hidden_files.on_select = [this]() {
show_hidden_files = !show_hidden_files;
button_show_hidden_files.set_color(show_hidden_files ? Color::green() : Color::dark_grey());
button_show_hidden_files.set_color(show_hidden_files ? *Theme::getInstance()->status_active : Theme::getInstance()->bg_dark->background);
reload_current();
};
}
+18 -18
View File
@@ -81,9 +81,9 @@ class FileManBaseView : public View {
{u".C8", &bitmap_icon_file_iq, ui::Color::dark_cyan()},
{u".C16", &bitmap_icon_file_iq, ui::Color::dark_cyan()},
{u".WAV", &bitmap_icon_file_wav, ui::Color::dark_magenta()},
{u".PPL", &bitmap_icon_file_iq, ui::Color::white()}, // Playlist/Replay
{u".REM", &bitmap_icon_remote, ui::Color::orange()}, // Remote
{u"", &bitmap_icon_file, ui::Color::light_grey()} // NB: Must be last.
{u".PPL", &bitmap_icon_file_iq, ui::Color::white()}, // Playlist/Replay
{u".REM", &bitmap_icon_remote, ui::Color::orange()}, // Remote
{u"", &bitmap_icon_file, Theme::getInstance()->fg_light->foreground} // NB: Must be last.
};
std::filesystem::path get_selected_full_path() const;
@@ -116,7 +116,7 @@ class FileManBaseView : public View {
bool show_hidden_files{false};
Labels labels{
{{0, 0}, "Path:", Color::light_grey()}};
{{0, 0}, "Path:", Theme::getInstance()->fg_light->foreground}};
Text text_current{
{6 * 8, 0 * 8, 24 * 8, 16},
@@ -166,8 +166,8 @@ private:
std::string buffer_ { };
Labels labels {
{ { 0 * 8, 1 * 16 }, "Path:", Color::light_grey() },
{ { 0 * 8, 6 * 16 }, "Filename:", Color::light_grey() },
{ { 0 * 8, 1 * 16 }, "Path:", Theme::getInstance()->fg_light->foreground },
{ { 0 * 8, 6 * 16 }, "Filename:",Theme::getInstance()->fg_light->foreground },
};
Text text_path {
@@ -234,62 +234,62 @@ class FileManagerView : public FileManBaseView {
{0 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_rename,
Color::dark_blue()};
Theme::getInstance()->fg_blue->foreground};
NewButton button_delete{
{9 * 8, 34 * 8, 4 * 8, 32},
{},
&bitmap_icon_trash,
Color::red()};
Theme::getInstance()->fg_red->foreground};
NewButton button_clean{
{13 * 8, 34 * 8, 4 * 8, 32},
{},
&bitmap_icon_clean,
Color::red()};
Theme::getInstance()->fg_red->foreground};
NewButton button_cut{
{9 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_cut,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_copy{
{13 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_copy,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_paste{
{17 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_paste,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_new_dir{
{22 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_new_dir,
Color::green()};
Theme::getInstance()->fg_green->foreground};
NewButton button_new_file{
{26 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_new_file,
Color::green()};
Theme::getInstance()->fg_green->foreground};
NewButton button_open_notepad{
{0 * 8, 34 * 8, 4 * 8, 32},
{},
&bitmap_icon_notepad,
Color::orange()};
Theme::getInstance()->fg_orange->foreground};
NewButton button_rename_timestamp{
{4 * 8, 29 * 8, 4 * 8, 32},
{},
&bitmap_icon_options_datetime,
Color::dark_blue(),
Theme::getInstance()->fg_blue->foreground,
/*vcenter*/ true};
NewButton button_open_iq_trim{
@@ -297,13 +297,13 @@ class FileManagerView : public FileManBaseView {
{4 * 8, 34 * 8, 4 * 8, 32},
{},
&bitmap_icon_trim,
Color::orange()};
Theme::getInstance()->fg_orange->foreground};
NewButton button_show_hidden_files{
{17 * 8, 34 * 8, 4 * 8, 32},
{},
&bitmap_icon_hide,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
};
} /* namespace ui */
@@ -21,7 +21,6 @@
*/
#include "ui_flash_utility.hpp"
#include "ui_styles.hpp"
#include "portapack_shared_memory.hpp"
#include "file_path.hpp"
@@ -83,6 +82,7 @@ FlashUtilityView::FlashUtilityView(NavigationView& nav)
menu_view.set_parent_rect({0, 3 * 8, 240, 33 * 8});
ensure_directory(apps_dir);
ensure_directory(firmware_dir);
auto add_firmware_items = [&](
@@ -102,10 +102,10 @@ FlashUtilityView::FlashUtilityView(NavigationView& nav)
}
};
add_firmware_items(firmware_dir, u"*.bin", ui::Color::red());
add_firmware_items(firmware_dir, u"*.tar", ui::Color::purple());
add_firmware_items(firmware_dir, u"*.bin", ui::Theme::getInstance()->fg_red->foreground);
add_firmware_items(firmware_dir, u"*.tar", ui::Theme::getInstance()->fg_cyan->foreground);
// add_firmware_items(user_firmware_folder,u"*.bin", ui::Color::purple());
// add_firmware_items(user_firmware_folder,u"*.bin", ui::Theme::getInstance()->fg_cyan->foreground);
}
void FlashUtilityView::firmware_selected(std::filesystem::path::string_type path) {
@@ -134,12 +134,12 @@ std::filesystem::path FlashUtilityView::extract_tar(std::filesystem::path::strin
//
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},
ui::Color::black());
Theme::getInstance()->bg_darkest->background);
painter.draw_string({12, 24}, this->nav_.style(), "Unpacking TAR file...");
auto res = UnTar::untar(path, [this](const std::string fileName) {
ui::Painter painter;
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, Theme::getInstance()->bg_darkest->background);
painter.draw_string({0, 60}, this->nav_.style(), fileName);
});
return res;
@@ -153,14 +153,14 @@ bool FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) {
}
if (path.empty() || !valid_firmware_file(path.c_str())) {
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, Styles::red, "BAD FIRMWARE FILE");
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, Theme::getInstance()->bg_darkest->background);
painter.draw_string({0, 60}, *Theme::getInstance()->fg_red, "BAD FIRMWARE FILE OR W/R ERR");
chThdSleepMilliseconds(5000);
return false;
}
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},
ui::Color::black());
Theme::getInstance()->bg_darkest->background);
painter.draw_string({12, 24}, this->nav_.style(), "This will take 15 seconds.");
painter.draw_string({12, 64}, this->nav_.style(), "Please wait while LED RX");
@@ -57,7 +57,7 @@ class FlashUtilityView : public View {
static Thread* thread;
Labels labels{
{{4, 4}, "Select firmware to flash:", Color::white()}};
{{4, 4}, "Select firmware to flash:", Theme::getInstance()->bg_darkest->foreground}};
MenuView menu_view{
{0, 2 * 8, 240, 26 * 8},
+5 -6
View File
@@ -29,7 +29,6 @@
#include "rtc_time.hpp"
#include "tone_key.hpp"
#include "ui_receiver.hpp"
#include "ui_styles.hpp"
#include "utility.hpp"
#include "file_path.hpp"
@@ -416,16 +415,16 @@ void FrequencyEditView::refresh_ui() {
auto is_repeater = entry_.type == freqman_type::Repeater;
auto has_freq_b = is_range || is_ham || is_repeater;
field_freq_b.set_style(has_freq_b ? &Styles::white : &Styles::grey);
field_step.set_style(is_range ? &Styles::white : &Styles::grey);
field_tone.set_style(is_ham ? &Styles::white : &Styles::grey);
field_freq_b.set_style(has_freq_b ? Theme::getInstance()->bg_darkest : Theme::getInstance()->fg_medium);
field_step.set_style(is_range ? Theme::getInstance()->bg_darkest : Theme::getInstance()->fg_medium);
field_tone.set_style(is_ham ? Theme::getInstance()->bg_darkest : Theme::getInstance()->fg_medium);
if (is_valid(entry_)) {
text_validation.set("Valid");
text_validation.set_style(&Styles::green);
text_validation.set_style(Theme::getInstance()->fg_green);
} else {
text_validation.set("Error");
text_validation.set_style(&Styles::red);
text_validation.set_style(Theme::getInstance()->fg_red);
}
}
+16 -16
View File
@@ -61,7 +61,7 @@ class FreqManBaseView : public View {
/* The top section (category) is 20px tall. */
Labels label_category{
{{0, 2}, "F:", Color::light_grey()}};
{{0, 2}, "F:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_category{
{3 * 8, 2},
@@ -97,7 +97,7 @@ class FrequencySaveView : public FreqManBaseView {
0};
Labels labels{
{{0 * 8, 6 * 16}, "Description:", Color::white()}};
{{0 * 8, 6 * 16}, "Description:", Theme::getInstance()->bg_darkest->foreground}};
TextField field_description{
{0 * 8, 7 * 16, 30 * 8, 1 * 16},
@@ -137,14 +137,14 @@ class FrequencyManagerView : public FreqManBaseView {
{23 * 8, 0 * 16, 7 * 4, 20},
{},
&bitmap_icon_new_file,
Color::white(),
Theme::getInstance()->bg_darkest->foreground,
true};
NewButton button_del_category{
{26 * 8 + 4, 0 * 16, 7 * 4, 20},
{},
&bitmap_icon_trash,
Color::red(),
Theme::getInstance()->fg_red->foreground,
true};
Button button_edit_entry{
@@ -153,7 +153,7 @@ class FrequencyManagerView : public FreqManBaseView {
Rectangle rect_padding{
{15 * 8, 14 * 16 - 4, 15 * 8, 1 * 16 + 4},
Color::grey()};
Theme::getInstance()->fg_medium->background};
Button button_edit_freq{
{0 * 8, 15 * 16, 15 * 8, 2 * 16},
@@ -167,14 +167,14 @@ class FrequencyManagerView : public FreqManBaseView {
{15 * 8, 15 * 16, 7 * 8 + 4, 2 * 16},
{},
&bitmap_icon_add,
Color::white(),
Theme::getInstance()->bg_darkest->foreground,
true};
NewButton button_del_entry{
{22 * 8 + 4, 15 * 16, 7 * 8 + 4, 2 * 16},
{},
&bitmap_icon_delete,
Color::red(),
Theme::getInstance()->fg_red->foreground,
true};
};
@@ -200,15 +200,15 @@ class FrequencyEditView : public View {
void populate_tone_options();
Labels labels{
{{5 * 8, 1 * 16}, "Edit Frequency Entry", Color::white()},
{{0 * 8, 3 * 16}, "Entry Type :", Color::light_grey()},
{{0 * 8, 4 * 16}, "Frequency A:", Color::light_grey()},
{{0 * 8, 5 * 16}, "Frequency B:", Color::light_grey()},
{{0 * 8, 6 * 16}, "Modulation :", Color::light_grey()},
{{0 * 8, 7 * 16}, "Bandwidth :", Color::light_grey()},
{{0 * 8, 8 * 16}, "Step :", Color::light_grey()},
{{0 * 8, 9 * 16}, "Tone Freq :", Color::light_grey()},
{{0 * 8, 10 * 16}, "Description:", Color::light_grey()},
{{5 * 8, 1 * 16}, "Edit Frequency Entry", Theme::getInstance()->bg_darkest->foreground},
{{0 * 8, 3 * 16}, "Entry Type :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 4 * 16}, "Frequency A:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Frequency B:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 6 * 16}, "Modulation :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "Bandwidth :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Step :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 9 * 16}, "Tone Freq :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "Description:", Theme::getInstance()->fg_light->foreground},
};
OptionsField field_type{
+3 -4
View File
@@ -30,7 +30,6 @@
#include "ui_record_view.hpp"
#include "ui_rssi.hpp"
#include "ui_spectrum.hpp"
#include "ui_styles.hpp"
#include "ui_tabview.hpp"
#include "app_settings.hpp"
@@ -117,8 +116,8 @@ class FskxRxMainView : public View {
FskRxAppConsoleView view_data{nav_, view_rect};
TabView tab_view{
{"Data", Color::yellow(), &view_data},
{"Stream", Color::cyan(), &view_stream}};
{"Data", Theme::getInstance()->fg_yellow->foreground, &view_data},
{"Stream", Theme::getInstance()->fg_cyan->foreground, &view_stream}};
void refresh_ui(rf::Frequency f);
void on_packet(uint32_t value, bool is_data);
@@ -148,7 +147,7 @@ class FskxRxMainView : public View {
{19 * 8 - 4, 40, 6 * 8, 4}};
Labels labels{
{{0 * 8, 3 * 16}, "Deviation:", Color::light_grey()},
{{0 * 8, 3 * 16}, "Deviation:", Theme::getInstance()->fg_light->foreground},
};
FrequencyField deviation_frequency{
+4 -4
View File
@@ -54,8 +54,8 @@ IQTrimView::IQTrimView(NavigationView& nav)
};
};
text_samples.set_style(&Styles::light_grey);
text_max.set_style(&Styles::light_grey);
text_samples.set_style(Theme::getInstance()->fg_light);
text_max.set_style(Theme::getInstance()->fg_light);
field_start.on_change = [this](int32_t v) {
if (field_end.value() < v)
@@ -149,9 +149,9 @@ void IQTrimView::refresh_ui() {
// show max power in red if amplification is too high, causing clipping
uint32_t clipping_limit = (fs::capture_file_sample_size(path_) == sizeof(complex8_t)) ? 0x80 : 0x8000;
if ((field_amplify.value() * info_->max_iq) > clipping_limit)
text_max.set_style(&Styles::red);
text_max.set_style(Theme::getInstance()->fg_red);
else
text_max.set_style(&Styles::light_grey);
text_max.set_style(Theme::getInstance()->fg_light);
set_dirty();
}
+13 -14
View File
@@ -28,7 +28,6 @@
#include "optional.hpp"
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_styles.hpp"
#include "ui_widget.hpp"
#include <array>
@@ -41,21 +40,21 @@ class TrimProgressUI {
public:
void show_reading() {
clear();
p.draw_string({6 * 8, 5 * 16}, Styles::yellow, "Reading Capture...");
p.draw_string({6 * 8, 5 * 16}, *Theme::getInstance()->fg_yellow, "Reading Capture...");
}
void show_trimming() {
clear();
p.draw_string({5 * 8, 5 * 16}, Styles::yellow, "Trimming Capture...");
p.draw_string({5 * 8, 5 * 16}, *Theme::getInstance()->fg_yellow, "Trimming Capture...");
}
void show_progress(uint8_t percent) {
auto width = percent * screen_width / 100;
p.draw_hline({0, 6 * 16 + 2}, width, Color::yellow());
p.draw_hline({0, 6 * 16 + 2}, width, Theme::getInstance()->fg_yellow->foreground);
}
void clear() {
p.fill_rectangle({0 * 8, 4 * 16, screen_width, 3 * 16}, Color::black());
p.fill_rectangle({0 * 8, 4 * 16, screen_width, 3 * 16}, Theme::getInstance()->bg_darkest->background);
}
auto get_callback() {
@@ -101,15 +100,15 @@ class IQTrimView : public View {
TrimProgressUI progress_ui{};
Labels labels{
{{0 * 8, 0 * 16}, "Capture File:", Color::light_grey()},
{{0 * 8, 6 * 16}, "Start :", Color::light_grey()},
{{0 * 8, 7 * 16}, "End :", Color::light_grey()},
{{0 * 8, 8 * 16}, "Samples:", Color::light_grey()},
{{0 * 8, 9 * 16}, "Max Pwr:", Color::light_grey()},
{{0 * 8, 10 * 16}, "Cutoff :", Color::light_grey()},
{{12 * 8, 10 * 16}, "%", Color::light_grey()},
{{0 * 8, 12 * 16}, "Amplify:", Color::light_grey()},
{{10 * 8, 12 * 16}, "x", Color::light_grey()},
{{0 * 8, 0 * 16}, "Capture File:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 6 * 16}, "Start :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "End :", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Samples:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 9 * 16}, "Max Pwr:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "Cutoff :", Theme::getInstance()->fg_light->foreground},
{{12 * 8, 10 * 16}, "%", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 12 * 16}, "Amplify:", Theme::getInstance()->fg_light->foreground},
{{10 * 8, 12 * 16}, "x", Theme::getInstance()->fg_light->foreground},
};
TextField field_path{
+3 -3
View File
@@ -169,9 +169,9 @@ LevelView::LevelView(NavigationView& nav)
rssi_resolution.set_selected_index(1);
// FILL STEP OPTIONS
freqman_set_step_option_short(step_mode);
freq_stats_rssi.set_style(&Styles::white);
freq_stats_db.set_style(&Styles::white);
freq_stats_rx.set_style(&Styles::white);
freq_stats_rssi.set_style(Theme::getInstance()->bg_darkest);
freq_stats_db.set_style(Theme::getInstance()->bg_darkest);
freq_stats_rx.set_style(Theme::getInstance()->bg_darkest);
}
void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
+2 -3
View File
@@ -38,7 +38,6 @@
#include "ui_mictx.hpp"
#include "ui_receiver.hpp"
#include "ui_spectrum.hpp"
#include "ui_styles.hpp"
namespace ui {
@@ -81,8 +80,8 @@ class LevelView : public View {
}};
Labels labels{
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
{{0 * 8, 1 * 16}, "BW: MODE: S: ", Color::light_grey()},
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 1 * 16}, "BW: MODE: S: ", Theme::getInstance()->fg_light->foreground},
};
LNAGainField field_lna{
@@ -49,12 +49,12 @@ int32_t GlassView::map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t
void GlassView::update_display_beep() {
if (beep_enabled) {
button_beep_squelch.set_style(&Styles::green);
button_beep_squelch.set_style(Theme::getInstance()->fg_green);
// bip-XXdb
button_beep_squelch.set_text("bip" + to_string_dec_int(beep_squelch, 3) + "db");
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
} else {
button_beep_squelch.set_style(&Styles::white);
button_beep_squelch.set_style(Theme::getInstance()->bg_darkest);
button_beep_squelch.set_text("bip OFF ");
}
}
@@ -305,10 +305,10 @@ void GlassView::plot_marker(uint8_t pos) {
{
shift_y = 16;
}
portapack::display.fill_rectangle({0, 100 + shift_y, SCREEN_W, 8}, Color::black()); // Clear old marker and whole marker rectangle btw
portapack::display.fill_rectangle({pos - 2, 100 + shift_y, 5, 3}, Color::red()); // Red marker top
portapack::display.fill_rectangle({pos - 1, 103 + shift_y, 3, 3}, Color::red()); // Red marker middle
portapack::display.fill_rectangle({pos, 106 + shift_y, 1, 2}, Color::red()); // Red marker bottom
portapack::display.fill_rectangle({0, 100 + shift_y, SCREEN_W, 8}, Theme::getInstance()->bg_darkest->background); // Clear old marker and whole marker rectangle btw
portapack::display.fill_rectangle({pos - 2, 100 + shift_y, 5, 3}, Theme::getInstance()->fg_red->foreground); // Red marker top
portapack::display.fill_rectangle({pos - 1, 103 + shift_y, 3, 3}, Theme::getInstance()->fg_red->foreground); // Red marker middle
portapack::display.fill_rectangle({pos, 106 + shift_y, 1, 2}, Theme::getInstance()->fg_red->foreground); // Red marker bottom
}
void GlassView::update_min(int32_t v) {
@@ -347,10 +347,10 @@ void GlassView::update_max(int32_t v) {
void GlassView::update_range_field() {
if (!locked_range) {
field_range.set_style(&Styles::white);
field_range.set_style(Theme::getInstance()->bg_darkest);
field_range.set_text(" " + to_string_dec_uint(search_span) + " ");
} else {
field_range.set_style(&Styles::red);
field_range.set_style(Theme::getInstance()->fg_red);
field_range.set_text(">" + to_string_dec_uint(search_span) + "<");
}
}
@@ -33,7 +33,6 @@
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_styles.hpp"
#include "string_format.hpp"
#include "analog_audio_app.hpp"
#include "spectrum_color_lut.hpp"
@@ -171,12 +170,12 @@ class GlassView : public View {
uint8_t ignore_dc = 0;
Labels labels{
{{0, 0 * 16}, "MIN: MAX: LNA VGA ", Color::light_grey()},
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Color::light_grey()},
{{0, 2 * 16}, "P:", Color::light_grey()},
{{0, 3 * 16}, "MARKER: MHz RXIQCAL", Color::light_grey()},
//{{0, 4 * 16}, "RES: STEPS:", Color::light_grey()}};
{{0, 4 * 16}, "RES: VOL:", Color::light_grey()}};
{{0, 0 * 16}, "MIN: MAX: LNA VGA ", Theme::getInstance()->fg_light->foreground},
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Theme::getInstance()->fg_light->foreground},
{{0, 2 * 16}, "P:", Theme::getInstance()->fg_light->foreground},
{{0, 3 * 16}, "MARKER: MHz RXIQCAL", Theme::getInstance()->fg_light->foreground},
//{{0, 4 * 16}, "RES: STEPS:", Theme::getInstance()->fg_light->foreground}};
{{0, 4 * 16}, "RES: VOL:", Theme::getInstance()->fg_light->foreground}};
NumberField field_frequency_min{
{4 * 8, 0 * 16},
+19 -7
View File
@@ -63,8 +63,8 @@ void MicTXView::update_vumeter() {
}
void MicTXView::update_tx_icon() {
tx_icon.set_foreground(transmitting ? Color::red() : Color::black());
tx_icon.set_background(transmitting ? Color::yellow() : Color::black());
tx_icon.set_foreground(transmitting ? Theme::getInstance()->fg_red->foreground : Theme::getInstance()->bg_darkest->background);
tx_icon.set_background(transmitting ? Theme::getInstance()->fg_yellow->foreground : Theme::getInstance()->bg_darkest->background);
}
void MicTXView::on_tx_progress(const bool done) {
@@ -269,16 +269,24 @@ void MicTXView::set_rxbw_options(void) {
}
}
void MicTXView::set_rxbw_defaults(bool use_app_settings) {
void MicTXView::set_rxbw_defaults(bool use_app_settings) { // Initially in that function we set up rxbw, but now also txbw.
if (use_app_settings) {
field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
field_rxbw.set_by_value(rxbw_index);
} else if (mic_mod_index == MIC_MOD_NFM) {
field_bw.set_value(10); // NFM TX bw 10k, RX bw 16k (2) default
field_rxbw.set_by_value(2);
field_bw.set_value(10); // NFM TX bw 10k, RX bw 16k (index 2) default
field_bw.set_range(1, 60); // In NFM , FM , we are limitting index modulation range (0.08 ..5) ; (Ex max dev 60khz/12k = 5)
field_bw.set_step(1);
field_rxbw.set_by_value(2); // 16k from the three options (8k5,11k,16k)
} else if (mic_mod_index == MIC_MOD_WFM) {
field_bw.set_value(75); // WFM TX bw 75K, RX bw 200k (0) default
field_bw.set_value(75); // WFM TX bw 75K, RX bw 200k (index 0) default
field_bw.set_range(1, 150); // In our case Mod. Index range (1,67 ...12,5) ; 150k/12k=12,5
field_bw.set_step(1);
field_rxbw.set_by_value(0);
} else if ((mic_mod_index == MIC_MOD_USB) | (mic_mod_index == MIC_MOD_LSB)) {
field_bw.set_value(3); // In SSB by default let's limit TX_BW to 3kHz.
field_bw.set_range(2, 3); // User TXBW GUI range to modify that SSB TX_BW to limit SSB radiated spectrum.
field_bw.set_step(1);
}
// field_bw is hidden in other modulation cases
}
@@ -482,7 +490,11 @@ MicTXView::MicTXView(
field_bw.hidden(false);
options_tone_key.hidden(false);
} else {
field_bw.hidden(true);
if ((mic_mod_index == MIC_MOD_USB) || (mic_mod_index == MIC_MOD_LSB)) {
field_bw.hidden(false);
} else {
field_bw.hidden(true);
}
options_tone_key.set_selected_index(0);
options_tone_key.hidden(true);
}
+21 -21
View File
@@ -147,27 +147,27 @@ class MicTXView : public View {
bool button_touch{false};
Labels labels_both{
{{3 * 8, 1 * 8}, "MIC-GAIN:", Color::light_grey()},
{{3 * 8, 3 * 8}, "F:", Color::light_grey()},
{{15 * 8, 3 * 8}, "FM TXBW: kHz", Color::light_grey()}, // to be more symetric and consistent to the below FM RXBW
{{18 * 8, (5 * 8)}, "Mode:", Color::light_grey()}, // now, no need to handle GAIN, Amp here It is handled by ui_transmitter.cpp
{{4 * 8, 10 * 8}, "LVL:", Color::light_grey()}, // we delete { {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
{{12 * 8, 10 * 8}, "ATT:", Color::light_grey()},
{{20 * 8, 10 * 8}, "DEC:", Color::light_grey()},
{{3 * 8, (13 * 8) - 5}, "TONE KEY:", Color::light_grey()},
{{3 * 8, (18 * 8) - 1}, "======== Receiver ========", Color::green()},
{{5 * 8, (23 * 8) + 2}, "VOL:", Color::light_grey()},
{{14 * 8, (23 * 8) + 2}, "RXBW:", Color::light_grey()}, // we remove the label "FM" because we will display all MOD types RX_BW.
{{20 * 8, (25 * 8) + 2}, "SQ:", Color::light_grey()},
{{5 * 8, (25 * 8) + 2}, "F_RX:", Color::light_grey()},
{{5 * 8, (27 * 8) + 2}, "LNA:", Color::light_grey()},
{{12 * 8, (27 * 8) + 2}, "VGA:", Color::light_grey()},
{{19 * 8, (27 * 8) + 2}, "AMP:", Color::light_grey()},
{{21 * 8, (31 * 8)}, "TX-IQ-CAL:", Color::light_grey()}};
{{3 * 8, 1 * 8}, "MIC-GAIN:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 3 * 8}, "F: MHz", Theme::getInstance()->fg_light->foreground},
{{18 * 8, 3 * 8}, "TXBW: kHz", Theme::getInstance()->fg_light->foreground}, // to be more symetric and consistent to the below FM RXBW
{{18 * 8, (5 * 8)}, "Mode:", Theme::getInstance()->fg_light->foreground}, // now, no need to handle GAIN, Amp here It is handled by ui_transmitter.cpp
{{4 * 8, 10 * 8}, "LVL:", Theme::getInstance()->fg_light->foreground}, // we delete { {11 * 8, 5 * 8 }, "Amp:", Theme::getInstance()->fg_light->foreground },
{{12 * 8, 10 * 8}, "ATT:", Theme::getInstance()->fg_light->foreground},
{{20 * 8, 10 * 8}, "DEC:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, (13 * 8) - 5}, "TONE KEY:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, (18 * 8) - 1}, "======== Receiver ========", Theme::getInstance()->fg_green->foreground},
{{5 * 8, (23 * 8) + 2}, "VOL:", Theme::getInstance()->fg_light->foreground},
{{14 * 8, (23 * 8) + 2}, "RXBW:", Theme::getInstance()->fg_light->foreground}, // we remove the label "FM" because we will display all MOD types RX_BW.
{{20 * 8, (25 * 8) + 2}, "SQ:", Theme::getInstance()->fg_light->foreground},
{{5 * 8, (25 * 8) + 2}, "F_RX:", Theme::getInstance()->fg_light->foreground},
{{5 * 8, (27 * 8) + 2}, "LNA:", Theme::getInstance()->fg_light->foreground},
{{12 * 8, (27 * 8) + 2}, "VGA:", Theme::getInstance()->fg_light->foreground},
{{19 * 8, (27 * 8) + 2}, "AMP:", Theme::getInstance()->fg_light->foreground},
{{21 * 8, (31 * 8)}, "TX-IQ-CAL:", Theme::getInstance()->fg_light->foreground}};
Labels labels_WM8731{
{{17 * 8, 1 * 8}, "Boost", Color::light_grey()}};
{{17 * 8, 1 * 8}, "Boost", Theme::getInstance()->fg_light->foreground}};
Labels labels_AK4951{
{{17 * 8, 1 * 8}, "ALC", Color::light_grey()}};
{{17 * 8, 1 * 8}, "ALC", Theme::getInstance()->fg_light->foreground}};
VuMeter vumeter{
{0 * 8, 1 * 8, 2 * 8, 33 * 8},
@@ -357,8 +357,8 @@ class MicTXView : public View {
Image tx_icon{
{6 * 8, 31 * 8 + 4, 16, 16},
&bitmap_icon_microphone,
Color::black(),
Color::black()};
Theme::getInstance()->bg_darkest->background,
Theme::getInstance()->bg_darkest->background};
MessageHandlerRegistration message_handler_lcd_sync{
Message::ID::DisplayFrameSync,
+6 -6
View File
@@ -39,12 +39,12 @@ class ModemSetupView : public View {
private:
Labels labels{
{{2 * 8, 11 * 8}, "Baudrate:", Color::light_grey()},
{{2 * 8, 13 * 8}, "Mark: Hz", Color::light_grey()},
{{2 * 8, 15 * 8}, "Space: Hz", Color::light_grey()},
{{140, 15 * 8}, "Repeat:", Color::light_grey()},
{{1 * 8, 6 * 8}, "Modem preset:", Color::light_grey()},
{{2 * 8, 22 * 8}, "Serial format:", Color::light_grey()}};
{{2 * 8, 11 * 8}, "Baudrate:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 13 * 8}, "Mark: Hz", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 15 * 8}, "Space: Hz", Theme::getInstance()->fg_light->foreground},
{{140, 15 * 8}, "Repeat:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 6 * 8}, "Modem preset:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 22 * 8}, "Serial format:", Theme::getInstance()->fg_light->foreground}};
NumberField field_baudrate{
{11 * 8, 11 * 8},
+5 -5
View File
@@ -103,11 +103,11 @@ class MorseView : public View {
bool run{false};
Labels labels{
{{4 * 8, 6 * 8}, "Speed: wps", Color::light_grey()},
{{4 * 8, 8 * 8}, "Tone: Hz", Color::light_grey()},
{{4 * 8, 10 * 8}, "Modulation:", Color::light_grey()},
{{4 * 8, 12 * 8}, "Loop:", Color::light_grey()},
{{1 * 8, 25 * 8}, "TX will last", Color::light_grey()}};
{{4 * 8, 6 * 8}, "Speed: wps", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 8 * 8}, "Tone: Hz", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 10 * 8}, "Modulation:", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 12 * 8}, "Loop:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 25 * 8}, "TX will last", Theme::getInstance()->fg_light->foreground}};
Checkbox checkbox_foxhunt{
{4 * 8, 16},
+1 -2
View File
@@ -21,7 +21,6 @@
*/
#include "ui_numbers.hpp"
#include "ui_styles.hpp"
#include "string_format.hpp"
#include "portapack.hpp"
@@ -145,7 +144,7 @@ void NumbersStationView::on_tick_second() {
armed_blink = not armed_blink;
if (armed_blink)
check_armed.set_style(&Styles::red);
check_armed.set_style(Theme::getInstance()->fg_red);
else
check_armed.set_style(&style());
+2 -2
View File
@@ -129,8 +129,8 @@ class NumbersStationView : public View {
void start_tx();
Labels labels{
{{2 * 8, 5 * 8}, "Voice: Flags:", Color::light_grey()},
{{1 * 8, 8 * 8}, "Code:", Color::light_grey()}};
{{2 * 8, 5 * 8}, "Voice: Flags:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 8 * 8}, "Code:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_voices{
{8 * 8, 1 * 8},
+8 -8
View File
@@ -141,8 +141,8 @@ class PlaylistView : public View {
ImageButton button_play{
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Color::green(),
Color::black()};
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
Text text_track{
{0 * 8, 3 * 16, 30 * 8, 16}};
@@ -151,37 +151,37 @@ class PlaylistView : public View {
{2 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_arrow_left,
Color::dark_grey()};
Theme::getInstance()->bg_dark->background};
NewButton button_next{
{6 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_arrow_right,
Color::dark_grey()};
Theme::getInstance()->bg_dark->background};
NewButton button_add{
{11 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_icon_new_file,
Color::orange()};
Theme::getInstance()->fg_orange->foreground};
NewButton button_delete{
{15 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_icon_delete,
Color::orange()};
Theme::getInstance()->fg_orange->foreground};
NewButton button_open{
{20 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_icon_load,
Color::dark_blue()};
Theme::getInstance()->fg_blue->foreground};
NewButton button_save{
{24 * 8, 4 * 16, 4 * 8, 2 * 16},
"",
&bitmap_icon_save,
Color::dark_blue()};
Theme::getInstance()->fg_blue->foreground};
spectrum::WaterfallView waterfall{};
+6 -6
View File
@@ -80,12 +80,12 @@ class POCSAGTXView : public View {
bool start_tx();
Labels labels{
{{3 * 8, 4 * 8}, "Bitrate:", Color::light_grey()},
{{3 * 8, 6 * 8}, "Address:", Color::light_grey()},
{{6 * 8, 8 * 8}, "Type:", Color::light_grey()},
{{2 * 8, 10 * 8}, "Function:", Color::light_grey()},
{{5 * 8, 12 * 8}, "Phase:", Color::light_grey()},
{{0 * 8, 14 * 8}, "Message:", Color::light_grey()}};
{{3 * 8, 4 * 8}, "Bitrate:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 6 * 8}, "Address:", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 8 * 8}, "Type:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 10 * 8}, "Function:", Theme::getInstance()->fg_light->foreground},
{{5 * 8, 12 * 8}, "Phase:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 14 * 8}, "Message:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_bitrate{
{11 * 8, 4 * 8},
+14 -14
View File
@@ -43,8 +43,8 @@ class RDSPSNView : public OptionTabView {
private:
Labels labels{
{{1 * 8, 3 * 8}, "Program Service Name", Color::light_grey()},
{{2 * 8, 7 * 8}, "PSN:", Color::light_grey()}};
{{1 * 8, 3 * 8}, "Program Service Name", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 8}, "PSN:", Theme::getInstance()->fg_light->foreground}};
Button button_set{
{18 * 8, 3 * 16, 80, 32},
@@ -75,8 +75,8 @@ class RDSRadioTextView : public OptionTabView {
private:
Labels labels{
{{2 * 8, 3 * 8}, "Radiotext", Color::light_grey()},
{{1 * 8, 6 * 8}, "Text:", Color::light_grey()}};
{{2 * 8, 3 * 8}, "Radiotext", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 6 * 8}, "Text:", Theme::getInstance()->fg_light->foreground}};
Text text_radiotext{
{1 * 8, 4 * 16, 28 * 8, 16},
@@ -92,7 +92,7 @@ class RDSDateTimeView : public OptionTabView {
private:
Labels labels{
{{44, 5 * 16}, "Not yet implemented", Color::red()}};
{{44, 5 * 16}, "Not yet implemented", Theme::getInstance()->error_dark->foreground}};
};
class RDSAudioView : public OptionTabView {
@@ -101,7 +101,7 @@ class RDSAudioView : public OptionTabView {
private:
Labels labels{
{{44, 5 * 16}, "Not yet implemented", Color::red()}};
{{44, 5 * 16}, "Not yet implemented", Theme::getInstance()->error_dark->foreground}};
};
class RDSThread {
@@ -168,16 +168,16 @@ class RDSView : public View {
RDSAudioView view_audio{view_rect};
TabView tab_view{
{"Name", Color::cyan(), &view_PSN},
{"Text", Color::green(), &view_radiotext},
{"Time", Color::yellow(), &view_datetime},
{"Audio", Color::orange(), &view_audio}};
{"Name", Theme::getInstance()->fg_cyan->foreground, &view_PSN},
{"Text", Theme::getInstance()->fg_green->foreground, &view_radiotext},
{"Time", Theme::getInstance()->fg_yellow->foreground, &view_datetime},
{"Audio", Theme::getInstance()->fg_orange->foreground, &view_audio}};
Labels labels{
{{0 * 8, 28}, "Program type:", Color::light_grey()},
//{ { 14 * 8, 16 + 8 }, "CC:", Color::light_grey() },
{{2 * 8, 28 + 16}, "Program ID:", Color::light_grey()},
//{ { 13 * 8, 32 + 8 }, "Cov:", Color::light_grey() },
{{0 * 8, 28}, "Program type:", Theme::getInstance()->fg_light->foreground},
//{ { 14 * 8, 16 + 8 }, "CC:", Theme::getInstance()->fg_light->foreground },
{{2 * 8, 28 + 16}, "Program ID:", Theme::getInstance()->fg_light->foreground},
//{ { 13 * 8, 32 + 8 }, "Cov:",Theme::getInstance()->fg_light->foreground },
};
OptionsField options_pty{
+40 -40
View File
@@ -65,16 +65,16 @@ void ReconView::reload_restart_recon() {
recon_resume();
}
if (scanner_mode) {
file_name.set_style(&Styles::red);
button_scanner_mode.set_style(&Styles::red);
file_name.set_style(Theme::getInstance()->fg_red);
button_scanner_mode.set_style(Theme::getInstance()->fg_red);
button_scanner_mode.set_text("SCAN");
} else {
file_name.set_style(&Styles::blue);
button_scanner_mode.set_style(&Styles::blue);
file_name.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_text("RECON");
}
if (frequency_list.size() > FREQMAN_MAX_PER_FILE) {
file_name.set_style(&Styles::yellow);
file_name.set_style(Theme::getInstance()->fg_yellow);
}
}
@@ -104,7 +104,7 @@ freqman_entry& ReconView::current_entry() {
void ReconView::set_loop_config(bool v) {
continuous = v;
button_loop_config.set_style(v ? &Styles::green : &Styles::white);
button_loop_config.set_style(v ? Theme::getInstance()->fg_green : Theme::getInstance()->bg_darkest);
persistent_memory::set_recon_continuous(continuous);
}
@@ -121,8 +121,8 @@ void ReconView::recon_stop_recording(bool exiting) {
} else {
button_audio_app.set_text("AUDIO");
}
button_audio_app.set_style(&Styles::white);
button_config.set_style(&Styles::white);
button_audio_app.set_style(Theme::getInstance()->bg_darkest);
button_config.set_style(Theme::getInstance()->bg_darkest);
}
}
@@ -171,23 +171,23 @@ void ReconView::update_description() {
void ReconView::colorize_waits() {
// colorize wait on match
if (wait == 0) {
field_wait.set_style(&Styles::blue);
field_wait.set_style(Theme::getInstance()->fg_blue);
} else if (wait >= 500) {
field_wait.set_style(&Styles::white);
field_wait.set_style(Theme::getInstance()->bg_darkest);
} else if (wait > -500 && wait < 500) {
field_wait.set_style(&Styles::red);
field_wait.set_style(Theme::getInstance()->fg_red);
} else if (wait <= -500) {
field_wait.set_style(&Styles::green);
field_wait.set_style(Theme::getInstance()->fg_green);
}
// colorize lock time if in SPARSE mode as in continuous the lock_wait time is disarmed at first lock count
if (recon_match_mode == RECON_MATCH_SPARSE) {
if ((recon_lock_duration / STATS_UPDATE_INTERVAL) <= recon_lock_nb_match) {
field_lock_wait.set_style(&Styles::yellow);
field_lock_wait.set_style(Theme::getInstance()->fg_yellow);
} else {
field_lock_wait.set_style(&Styles::white);
field_lock_wait.set_style(Theme::getInstance()->bg_darkest);
}
} else {
field_lock_wait.set_style(&Styles::white);
field_lock_wait.set_style(Theme::getInstance()->bg_darkest);
}
}
@@ -259,17 +259,17 @@ void ReconView::recon_redraw() {
text_nb_locks.set(to_string_dec_uint(freq_lock) + "/" + to_string_dec_uint(recon_lock_nb_match));
if (freq_lock == 0) {
// NO FREQ LOCK, ONGOING STANDARD SCANNING
big_display.set_style(&Styles::white);
big_display.set_style(Theme::getInstance()->bg_darkest);
if (recon)
button_pause.set_text("<PAUSE>");
else
button_pause.set_text("<RESUME>");
} else if (freq_lock == 1 && recon_lock_nb_match != 1) {
// STARTING LOCK FREQ
big_display.set_style(&Styles::yellow);
big_display.set_style(Theme::getInstance()->fg_yellow);
button_pause.set_text("<SKPLCK>");
} else if (freq_lock >= recon_lock_nb_match) {
big_display.set_style(&Styles::green);
big_display.set_style(Theme::getInstance()->fg_green);
button_pause.set_text("<UNLOCK>");
}
}
@@ -591,18 +591,18 @@ ReconView::ReconView(NavigationView& nav)
current_entry().bandwidth = freqman_invalid_index;
current_entry().step = def_step;
big_display.set_style(&Styles::white); // Back to white color
big_display.set_style(Theme::getInstance()->bg_darkest); // Back to white color
freq_stats.set_style(&Styles::white);
freq_stats.set_style(Theme::getInstance()->bg_darkest);
freq_stats.set("0/0/0");
text_cycle.set_text("1");
text_max.set("/1");
button_scanner_mode.set_style(&Styles::white);
button_scanner_mode.set_style(Theme::getInstance()->bg_darkest);
button_scanner_mode.set_text("MANUAL");
file_name.set_style(&Styles::white);
file_name.set_style(Theme::getInstance()->bg_darkest);
file_name.set("MANUAL => " + output_file);
desc_cycle.set_style(&Styles::white);
desc_cycle.set_style(Theme::getInstance()->bg_darkest);
last_entry.modulation = freqman_invalid_index;
last_entry.bandwidth = freqman_invalid_index;
@@ -648,12 +648,12 @@ ReconView::ReconView(NavigationView& nav)
manual_mode = false;
if (scanner_mode) {
scanner_mode = false;
button_scanner_mode.set_style(&Styles::blue);
button_scanner_mode.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_text("RECON");
button_remove.set_text("<REMOVE>");
} else {
scanner_mode = true;
button_scanner_mode.set_style(&Styles::red);
button_scanner_mode.set_style(Theme::getInstance()->fg_red);
button_scanner_mode.set_text("SCAN");
button_remove.set_text("<DELETE>");
}
@@ -726,7 +726,7 @@ ReconView::ReconView(NavigationView& nav)
};
// PRE-CONFIGURATION:
button_scanner_mode.set_style(&Styles::blue);
button_scanner_mode.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_text("RECON");
file_name.set("=>");
@@ -772,14 +772,14 @@ void ReconView::frequency_file_load() {
std::string file_input = input_file; // default recon mode
if (scanner_mode) {
file_input = output_file;
file_name.set_style(&Styles::red);
button_scanner_mode.set_style(&Styles::red);
desc_cycle.set_style(&Styles::red);
file_name.set_style(Theme::getInstance()->fg_red);
button_scanner_mode.set_style(Theme::getInstance()->fg_red);
desc_cycle.set_style(Theme::getInstance()->fg_red);
button_scanner_mode.set_text("SCAN");
} else {
file_name.set_style(&Styles::blue);
button_scanner_mode.set_style(&Styles::blue);
desc_cycle.set_style(&Styles::blue);
file_name.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_style(Theme::getInstance()->fg_blue);
desc_cycle.set_style(Theme::getInstance()->fg_blue);
button_scanner_mode.set_text("RECON");
}
@@ -791,7 +791,7 @@ void ReconView::frequency_file_load() {
.load_hamradios = load_hamradios,
.load_repeaters = load_repeaters};
if (!load_freqman_file(file_input, frequency_list, options) || frequency_list.empty()) {
file_name.set_style(&Styles::red);
file_name.set_style(Theme::getInstance()->fg_red);
desc_cycle.set("...empty file...");
frequency_list.clear();
text_cycle.set_text(" ");
@@ -799,7 +799,7 @@ void ReconView::frequency_file_load() {
}
if (frequency_list.size() > FREQMAN_MAX_PER_FILE) {
file_name.set_style(&Styles::yellow);
file_name.set_style(Theme::getInstance()->fg_yellow);
}
reset_indexes();
@@ -888,13 +888,13 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
audio_output_start();
// contents of a possible recon_start_recording(), but not yet since it's only called once
if (auto_record_locked && !is_recording) {
button_audio_app.set_style(&Styles::red);
button_audio_app.set_style(Theme::getInstance()->fg_red);
if (field_mode.selected_index_value() == SPEC_MODULATION) {
button_audio_app.set_text("RAW REC");
} else
button_audio_app.set_text("WAV REC");
record_view->start();
button_config.set_style(&Styles::light_grey); // disable config while recording as it's causing an IO error pop up at exit
button_config.set_style(Theme::getInstance()->fg_light); // disable config while recording as it's causing an IO error pop up at exit
is_recording = true;
}
// FREQ IS STRONG: GREEN and recon will pause when on_statistics_update()
@@ -1106,7 +1106,7 @@ void ReconView::recon_pause() {
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio_output_start();
big_display.set_style(&Styles::white);
big_display.set_style(Theme::getInstance()->bg_darkest);
button_pause.set_text("<RESUME>"); // PAUSED, show resume
}
@@ -1118,7 +1118,7 @@ void ReconView::recon_resume() {
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
big_display.set_style(&Styles::white);
big_display.set_style(Theme::getInstance()->bg_darkest);
button_pause.set_text("<PAUSE>");
}
@@ -1401,8 +1401,8 @@ void ReconView::start_repeat() {
std::string delay_message = "TX DELAY: " + to_string_dec_uint(delay) + "s";
// update display information
p.fill_rectangle({0, (SCREEN_H / 2) - 16, SCREEN_W, 64}, Color::light_grey());
p.draw_string({(SCREEN_W / 2) - 7 * 8, SCREEN_H / 2}, Styles::red, delay_message);
p.fill_rectangle({0, (SCREEN_H / 2) - 16, SCREEN_W, 64}, Theme::getInstance()->fg_light->foreground);
p.draw_string({(SCREEN_W / 2) - 7 * 8, SCREEN_H / 2}, *Theme::getInstance()->fg_red, delay_message);
// sleep 1 second
chThdSleepMilliseconds(1000);
+5 -6
View File
@@ -27,7 +27,6 @@
#include "ui.hpp"
#include "receiver_model.hpp"
#include "ui_receiver.hpp"
#include "ui_styles.hpp"
#include "freqman.hpp"
#include "analog_audio_app.hpp"
#include "audio.hpp"
@@ -219,11 +218,11 @@ class ReconView : public View {
std::unique_ptr<RecordView> record_view{};
Labels labels{
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
{{3 * 8, 8 * 16}, "START END", Color::light_grey()},
{{0 * 8, (22 * 8)}, " S: ", Color::light_grey()},
{{0 * 8, (24 * 8) + 4}, "NBLCKS:x W,L: , ", Color::light_grey()},
{{0 * 8, (26 * 8) + 4}, "MODE: , SQUELCH: ", Color::light_grey()}};
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 8 * 16}, "START END", Theme::getInstance()->fg_light->foreground},
{{0 * 8, (22 * 8)}, " S: ", Theme::getInstance()->fg_light->foreground},
{{0 * 8, (24 * 8) + 4}, "NBLCKS:x W,L: , ", Theme::getInstance()->fg_light->foreground},
{{0 * 8, (26 * 8) + 4}, "MODE: , SQUELCH: ", Theme::getInstance()->fg_light->foreground}};
LNAGainField field_lna{
{4 * 8, 0 * 16}};
@@ -137,15 +137,15 @@ ReconSetupViewMore::ReconSetupViewMore(NavigationView& nav, Rect parent_rect)
&field_repeat_delay});
// tx options have to be in yellow to inform the users that activating them will make the device transmit
checkbox_repeat_recorded.set_style(&Styles::yellow);
field_repeat_file_mode.set_style(&Styles::yellow);
text_repeat_nb.set_style(&Styles::yellow);
field_repeat_nb.set_style(&Styles::yellow);
checkbox_repeat_amp.set_style(&Styles::yellow);
text_repeat_gain.set_style(&Styles::yellow);
field_repeat_gain.set_style(&Styles::yellow);
text_repeat_delay.set_style(&Styles::yellow);
field_repeat_delay.set_style(&Styles::yellow);
checkbox_repeat_recorded.set_style(Theme::getInstance()->fg_yellow);
field_repeat_file_mode.set_style(Theme::getInstance()->fg_yellow);
text_repeat_nb.set_style(Theme::getInstance()->fg_yellow);
field_repeat_nb.set_style(Theme::getInstance()->fg_yellow);
checkbox_repeat_amp.set_style(Theme::getInstance()->fg_yellow);
text_repeat_gain.set_style(Theme::getInstance()->fg_yellow);
field_repeat_gain.set_style(Theme::getInstance()->fg_yellow);
text_repeat_delay.set_style(Theme::getInstance()->fg_yellow);
field_repeat_delay.set_style(Theme::getInstance()->fg_yellow);
checkbox_load_freqs.set_value(persistent_memory::recon_load_freqs());
checkbox_load_repeaters.set_value(persistent_memory::recon_load_repeaters());
@@ -30,7 +30,6 @@
#include "ui_tabview.hpp"
#include "ui_navigation.hpp"
#include "string_format.hpp"
#include "ui_styles.hpp"
// 1Mhz helper
#ifdef OneMHz
@@ -60,7 +59,7 @@
// screen size helper
#define SCREEN_W 240
//#define SCREEN_H 320
// #define SCREEN_H 320
// recon settings nb params
#define RECON_SETTINGS_NB_PARAMS 7
@@ -226,8 +225,8 @@ class ReconSetupView : public View {
ReconSetupViewMore viewMore{nav_, view_rect};
TabView tab_view{
{"Main", Color::cyan(), &viewMain},
{"More", Color::green(), &viewMore}};
{"Main", Theme::getInstance()->fg_cyan->foreground, &viewMain},
{"More", Theme::getInstance()->fg_green->foreground, &viewMore}};
Button button_save{
{9 * 8, 255, 14 * 8, 40},
+2 -2
View File
@@ -177,11 +177,11 @@ void RemoteButton::paint(Painter& painter) {
// Add a border on the highlighted button.
if (has_focus() || highlighted()) {
auto r = screen_rect();
painter.draw_rectangle(r, Color::white());
painter.draw_rectangle(r, Theme::getInstance()->bg_darkest->foreground);
auto p = r.location() + Point{1, 1};
auto s = Size{r.size().width() - 2, r.size().height() - 2};
painter.draw_rectangle({p, s}, Color::light_grey());
painter.draw_rectangle({p, s}, Theme::getInstance()->fg_light->foreground);
}
};
+9 -9
View File
@@ -200,15 +200,15 @@ class RemoteEntryEditView : public View {
void load_path(std::filesystem::path&& path);
Labels labels{
{{2 * 8, 1 * 16}, "Name:", Color::light_grey()},
{{2 * 8, 2 * 16}, "Path:", Color::light_grey()},
{{2 * 8, 3 * 16}, "Freq:", Color::light_grey()},
{{17 * 8, 3 * 16}, "MHz", Color::light_grey()},
{{2 * 8, 4 * 16}, "Rate:", Color::light_grey()},
{{2 * 8, 5 * 16}, "Icon:", Color::light_grey()},
{{2 * 8, 6 * 16}, "FG Color:", Color::light_grey()},
{{2 * 8, 7 * 16}, "BG Color:", Color::light_grey()},
{{8 * 8, 9 * 16}, "Button preview", Color::light_grey()},
{{2 * 8, 1 * 16}, "Name:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 2 * 16}, "Path:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 3 * 16}, "Freq:", Theme::getInstance()->fg_light->foreground},
{{17 * 8, 3 * 16}, "MHz", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 4 * 16}, "Rate:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 5 * 16}, "Icon:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 6 * 16}, "FG Color:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 16}, "BG Color:", Theme::getInstance()->fg_light->foreground},
{{8 * 8, 9 * 16}, "Button preview", Theme::getInstance()->fg_light->foreground},
};
TextField field_name{{8 * 8, 1 * 16, 20 * 8, 1 * 16}, {}};
+6 -6
View File
@@ -185,16 +185,16 @@ void ScannerView::bigdisplay_update(int32_t v) {
switch (bigdisplay_current_color) {
case BDC_GREY:
big_display.set_style(&Styles::grey);
big_display.set_style(Theme::getInstance()->fg_medium);
break;
case BDC_YELLOW:
big_display.set_style(&Styles::yellow);
big_display.set_style(Theme::getInstance()->fg_yellow);
break;
case BDC_GREEN:
big_display.set_style(&Styles::green);
big_display.set_style(Theme::getInstance()->fg_green);
break;
case BDC_RED:
big_display.set_style(&Styles::red);
big_display.set_style(Theme::getInstance()->fg_red);
break;
default:
break;
@@ -280,10 +280,10 @@ void ScannerView::show_max_index() { // show total number of freqs to scan
field_current_index.set_text("<->");
if (entries.size() == FREQMAN_MAX_PER_FILE) {
text_max_index.set_style(&Styles::red);
text_max_index.set_style(Theme::getInstance()->fg_red);
text_max_index.set("/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE) + " (DB MAX!)");
} else {
text_max_index.set_style(&Styles::grey);
text_max_index.set_style(Theme::getInstance()->fg_medium);
text_max_index.set("/ " + to_string_dec_uint(entries.size()));
}
}
+6 -7
View File
@@ -34,11 +34,10 @@
#include "ui.hpp"
#include "ui_mictx.hpp"
#include "ui_receiver.hpp"
#include "ui_styles.hpp"
#define SCANNER_SLEEP_MS 50 // ms that Scanner Thread sleeps per loop
#define STATISTICS_UPDATES_PER_SEC 10
#define MAX_FREQ_LOCK 10 //# of 50ms cycles scanner locks into freq when signal detected, to verify signal is not spurious
#define MAX_FREQ_LOCK 10 // # of 50ms cycles scanner locks into freq when signal detected, to verify signal is not spurious
namespace ui {
@@ -172,12 +171,12 @@ class ScannerView : public View {
};
Labels labels{
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL:", Color::light_grey()},
{{0 * 8, 1 * 16}, "BW: SQ: Wsa: Wsl:", Color::light_grey()},
{{0 * 8, 10 * 16}, "SRCH START SEARCH END SWITCH", Color::light_grey()},
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 1 * 16}, "BW: SQ: Wsa: Wsl:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "SRCH START SEARCH END SWITCH", Theme::getInstance()->fg_light->foreground},
{{0 * 8, (26 * 8) + 4}, "MODE:", Color::light_grey()},
{{11 * 8, (26 * 8) + 4}, "STEP:", Color::light_grey()},
{{0 * 8, (26 * 8) + 4}, "MODE:", Theme::getInstance()->fg_light->foreground},
{{11 * 8, (26 * 8) + 4}, "STEP:", Theme::getInstance()->fg_light->foreground},
};
LNAGainField field_lna{
+1 -1
View File
@@ -56,7 +56,7 @@ void ScriptView::setup_list() {
menu_view.clear();
/*for (n = 0; n < frequencies.size(); n++) {
menu_view.add_item({ freqman_item_string(frequencies[n]), ui::Color::white(), nullptr, [this](){ on_frequency_select(); } });
menu_view.add_item({ freqman_item_string(frequencies[n]), Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ on_frequency_select(); } });
}*/
menu_view.set_parent_rect({0, 0, 240, 168});
+3 -3
View File
@@ -34,13 +34,13 @@ SdOverUsbView::SdOverUsbView(NavigationView& nav)
ui::Painter painter;
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},
ui::Color::black());
Theme::getInstance()->bg_darkest->background);
painter.draw_bitmap(
{portapack::display.width() / 2 - 8, portapack::display.height() / 2 - 8},
bitmap_icon_hackrf,
ui::Color::yellow(),
ui::Color::black());
Theme::getInstance()->bg_darkest->foreground,
Theme::getInstance()->bg_darkest->background);
sdcDisconnect(&SDCD1);
sdcStop(&SDCD1);
+5 -5
View File
@@ -46,11 +46,11 @@ class SdOverUsbView : public View {
NavigationView& nav_;
Labels labels{
{{3 * 8, 2 * 16}, "Click Run to start the", Color::white()},
{{3 * 8, 3 * 16}, "USB Mass Storage Mode.", Color::white()},
{{3 * 8, 5 * 16}, "It can take up to 20s", Color::white()},
{{3 * 8, 6 * 16}, "for the drive to be", Color::white()},
{{3 * 8, 7 * 16}, "available.", Color::white()},
{{3 * 8, 2 * 16}, "Click Run to start the", Theme::getInstance()->bg_darkest->foreground},
{{3 * 8, 3 * 16}, "USB Mass Storage Mode.", Theme::getInstance()->bg_darkest->foreground},
{{3 * 8, 5 * 16}, "It can take up to 20s", Theme::getInstance()->bg_darkest->foreground},
{{3 * 8, 6 * 16}, "for the drive to be", Theme::getInstance()->bg_darkest->foreground},
{{3 * 8, 7 * 16}, "available.", Theme::getInstance()->bg_darkest->foreground},
};
Button button_run{
+9 -9
View File
@@ -80,11 +80,11 @@ SearchView::SearchView(
nav.push<FrequencySaveView>(entry.frequency);
};
text_mean.set_style(&Styles::grey);
text_slices.set_style(&Styles::grey);
text_rate.set_style(&Styles::grey);
progress_timers.set_style(&Styles::grey);
big_display.set_style(&Styles::grey);
text_mean.set_style(Theme::getInstance()->fg_medium);
text_slices.set_style(Theme::getInstance()->fg_medium);
text_rate.set_style(Theme::getInstance()->fg_medium);
progress_timers.set_style(Theme::getInstance()->fg_medium);
big_display.set_style(Theme::getInstance()->fg_medium);
field_frequency_min.set_step(100'000);
bind(field_frequency_min, settings_.freq_min, nav, [this](auto) {
@@ -184,7 +184,7 @@ void SearchView::do_detection() {
recent_entries_view.set_dirty();
text_infos.set("Locked ! ");
big_display.set_style(&Styles::green);
big_display.set_style(Theme::getInstance()->fg_green);
locked = true;
locked_bin = bin_max;
@@ -209,7 +209,7 @@ void SearchView::do_detection() {
recent_entries_view.set_dirty();
text_infos.set("Listening");
big_display.set_style(&Styles::grey);
big_display.set_style(Theme::getInstance()->fg_medium);
}
}
}
@@ -219,10 +219,10 @@ void SearchView::do_detection() {
search_counter++;
// Refresh red tick
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Color::black());
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Theme::getInstance()->fg_red->background);
if (bin_max > -1) {
last_tick_pos = (Coord)(bin_max / slices_nb);
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Color::red());
portapack::display.fill_rectangle({last_tick_pos, 90, 1, 6}, Theme::getInstance()->fg_red->foreground);
}
}
+6 -7
View File
@@ -26,7 +26,6 @@
#include "radio_state.hpp"
#include "spectrum_color_lut.hpp"
#include "ui_receiver.hpp"
#include "ui_styles.hpp"
namespace ui {
@@ -162,12 +161,12 @@ class SearchView : public View {
RecentEntriesView<RecentEntries<SearchRecentEntry>> recent_entries_view{columns, recent};
Labels labels{
{{1 * 8, 0}, "Min: Max: LNA VGA", Color::light_grey()},
{{1 * 8, 4 * 8}, "Trig: /255 Mean: /255", Color::light_grey()},
{{1 * 8, 6 * 8}, "Slices: /32 Rate: Hz", Color::light_grey()},
{{6 * 8, 10 * 8}, "Timer Status", Color::light_grey()},
{{1 * 8, 25 * 8}, "Accuracy +/-4.9kHz", Color::light_grey()},
{{26 * 8, 25 * 8}, "MHz", Color::light_grey()}};
{{1 * 8, 0}, "Min: Max: LNA VGA", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 4 * 8}, "Trig: /255 Mean: /255", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 6 * 8}, "Slices: /32 Rate: Hz", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 10 * 8}, "Timer Status", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 25 * 8}, "Accuracy +/-4.9kHz", Theme::getInstance()->fg_light->foreground},
{{26 * 8, 25 * 8}, "MHz", Theme::getInstance()->fg_light->foreground}};
FrequencyField field_frequency_min{
{1 * 8, 1 * 16}};
+45 -6
View File
@@ -46,11 +46,12 @@ using namespace portapack;
namespace fs = std::filesystem;
#include "string_format.hpp"
#include "ui_styles.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "cpld_update.hpp"
#include "config_mode.hpp"
extern ui::SystemView* system_view_ptr;
namespace pmem = portapack::persistent_memory;
namespace ui {
@@ -228,9 +229,9 @@ SetRadioView::SetRadioView(
value_source_frequency.set(clock_manager.get_freq());
// Make these Text controls look like Labels.
label_source.set_style(&Styles::light_grey);
value_source.set_style(&Styles::light_grey);
value_source_frequency.set_style(&Styles::light_grey);
label_source.set_style(Theme::getInstance()->fg_light);
value_source.set_style(Theme::getInstance()->fg_light);
value_source_frequency.set_style(Theme::getInstance()->fg_light);
SetFrequencyCorrectionModel model{
static_cast<int8_t>(pmem::correction_ppb() / 1000), 0};
@@ -575,7 +576,7 @@ SetPersistentMemoryView::SetPersistentMemoryView(NavigationView& nav) {
&button_return,
});
text_pmem_status.set_style(&Styles::yellow);
text_pmem_status.set_style(Theme::getInstance()->fg_yellow);
check_use_sdcard_for_pmem.set_value(pmem::should_use_sdcard_for_pmem());
check_use_sdcard_for_pmem.on_select = [this](Checkbox&, bool v) {
@@ -737,7 +738,7 @@ AppSettingsView::AppSettingsView(
auto path = settings_dir / entry.path();
menu_view.add_item({path.filename().string().substr(0, 26),
ui::Color::dark_cyan(),
ui::Theme::getInstance()->fg_darkcyan->foreground,
&bitmap_icon_file_text,
[this, path](KeyEvent) {
nav_.push<TextEditorView>(path);
@@ -910,6 +911,43 @@ void SetAutostartView::focus() {
options.focus();
}
/* SetThemeView ************************************/
SetThemeView::SetThemeView(NavigationView& nav) {
add_children({&labels,
&button_save,
&button_cancel,
&options,
&checkbox_menuset});
button_save.on_select = [&nav, this](Button&) {
if (selected < Theme::ThemeId::MAX && (uint8_t)selected != portapack::persistent_memory::ui_theme_id()) {
portapack::persistent_memory::set_ui_theme_id((uint8_t)selected);
Theme::SetTheme((Theme::ThemeId)selected);
if (checkbox_menuset.value()) {
pmem::set_menu_color(Theme::getInstance()->bg_medium->background);
}
send_system_refresh();
}
nav.pop();
};
checkbox_menuset.set_value(true);
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
options.on_change = [this](size_t, OptionsField::value_t v) {
selected = v;
};
options.set_selected_index(portapack::persistent_memory::ui_theme_id());
}
void SetThemeView::focus() {
options.focus();
}
/* SettingsMenuView **************************************/
SettingsMenuView::SettingsMenuView(NavigationView& nav)
@@ -937,6 +975,7 @@ void SettingsMenuView::on_populate() {
//{"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [this]() { nav_.push<SetQRCodeView>(); }},
{"Brightness", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push<SetFakeBrightnessView>(); }},
{"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>(); }},
{"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetAutostartView>(); }},
});
}
+105 -65
View File
@@ -65,14 +65,14 @@ class SetDateTimeView : public View {
std::vector<option_t> month_options = {{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6}, {"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}};
Labels labels{
{{1 * 8, 1 * 16}, "Adjust the RTC clock date &", Color::light_grey()},
{{1 * 8, 2 * 16}, "time. If clock resets after", Color::light_grey()},
{{1 * 8, 3 * 16}, "reboot, coin batt. is dead. ", Color::light_grey()},
{{1 * 8, 5 * 16 - 2}, "YYYY-MM-DD HH:MM:SS DoW DoY", Color::grey()},
{{5 * 8, 6 * 16}, "- - : :", Color::light_grey()},
{{1 * 8, 11 * 16}, "DST adds 1 hour to RTC time.", Color::light_grey()},
{{0 * 8, 12 * 16}, "Start: 0:00 on Nth DDD in", Color::light_grey()},
{{0 * 8, 13 * 16}, "End: 1:00 on Nth DDD in", Color::light_grey()}};
{{1 * 8, 1 * 16}, "Adjust the RTC clock date &", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "time. If clock resets after", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "reboot, coin batt. is dead. ", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 5 * 16 - 2}, "YYYY-MM-DD HH:MM:SS DoW DoY", Theme::getInstance()->fg_medium->foreground},
{{5 * 8, 6 * 16}, "- - : :", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 11 * 16}, "DST adds 1 hour to RTC time.", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 12 * 16}, "Start: 0:00 on Nth DDD in", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, "End: 1:00 on Nth DDD in", Theme::getInstance()->fg_light->foreground}};
NumberField field_year{
{1 * 8, 6 * 16},
@@ -210,8 +210,8 @@ class SetRadioView : public View {
""};
Labels labels_correction{
{{2 * 8, 3 * 16}, "Frequency correction:", Color::light_grey()},
{{6 * 8, 4 * 16}, "PPM", Color::light_grey()},
{{2 * 8, 3 * 16}, "Frequency correction:", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 4 * 16}, "PPM", Theme::getInstance()->fg_light->foreground},
};
NumberField field_ppm{
@@ -233,13 +233,13 @@ class SetRadioView : public View {
SymField::Type::Dec};
Labels labels_clkout_khz{
{{26 * 8, 6 * 16}, "kHz", Color::light_grey()}};
{{26 * 8, 6 * 16}, "kHz", Theme::getInstance()->fg_light->foreground}};
Labels labels_bias{
{{4 * 8 + 4, 8 * 16}, "CAUTION: Ensure that all", Color::red()},
{{5 * 8 + 0, 9 * 16}, "devices attached to the", Color::red()},
{{6 * 8 + 0, 10 * 16}, "antenna connector can", Color::red()},
{{6 * 8 + 4, 11 * 16}, "accept a DC voltage!", Color::red()}};
{{4 * 8 + 4, 8 * 16}, "CAUTION: Ensure that all", Theme::getInstance()->error_dark->foreground},
{{5 * 8 + 0, 9 * 16}, "devices attached to the", Theme::getInstance()->error_dark->foreground},
{{6 * 8 + 0, 10 * 16}, "antenna connector can", Theme::getInstance()->error_dark->foreground},
{{6 * 8 + 4, 11 * 16}, "accept a DC voltage!", Theme::getInstance()->error_dark->foreground}};
Checkbox check_bias{
{18, 12 * 16},
@@ -319,7 +319,7 @@ class SetUIView : public View {
"Back button in menu"};
Labels labels{
{{3 * 8, 13 * 16}, "Show/Hide Status Icons", Color::light_grey()},
{{3 * 8, 13 * 16}, "Show/Hide Status Icons", Theme::getInstance()->fg_light->foreground},
};
ImageToggle toggle_camera{
@@ -390,8 +390,8 @@ class SetSDCardView : public View {
private:
Labels labels{
// 01234567890123456789012345678
{{1 * 8, 120 - 48}, " HIGH SPEED SDCARD IO ", Color::light_grey()},
{{1 * 8, 120 - 32}, " May or may not work !! ", Color::light_grey()}};
{{1 * 8, 120 - 48}, " HIGH SPEED SDCARD IO ", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 120 - 32}, " May or may not work !! ", Theme::getInstance()->fg_light->foreground}};
Checkbox checkbox_sdcard_speed{
{2 * 8, 120},
@@ -425,11 +425,11 @@ class SetConverterSettingsView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Options for working with", Color::light_grey()},
{{1 * 8, 2 * 16}, "up/down converter hardware", Color::light_grey()},
{{1 * 8, 3 * 16}, "like a Ham It Up.", Color::light_grey()},
{{2 * 8, 9 * 16 - 2}, "Conversion frequency:", Color::light_grey()},
{{18 * 8, 10 * 16}, "MHz", Color::light_grey()},
{{1 * 8, 1 * 16}, "Options for working with", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "up/down converter hardware", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "like a Ham It Up.", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 9 * 16 - 2}, "Conversion frequency:", Theme::getInstance()->fg_light->foreground},
{{18 * 8, 10 * 16}, "MHz", Theme::getInstance()->fg_light->foreground},
};
Checkbox check_show_converter{
@@ -469,13 +469,13 @@ class SetFrequencyCorrectionView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Frequency correction allows", Color::light_grey()},
{{1 * 8, 2 * 16}, "RX and TX frequencies to be", Color::light_grey()},
{{1 * 8, 3 * 16}, "adjusted for all apps.", Color::light_grey()},
{{2 * 8, 6 * 16}, "RX Adjustment Frequency", Color::light_grey()},
{{18 * 8, 7 * 16}, "MHz", Color::light_grey()},
{{2 * 8, 9 * 16}, "TX Adjustment Frequency", Color::light_grey()},
{{18 * 8, 10 * 16}, "MHz", Color::light_grey()},
{{1 * 8, 1 * 16}, "Frequency correction allows", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "RX and TX frequencies to be", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "adjusted for all apps.", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 6 * 16}, "RX Adjustment Frequency", Theme::getInstance()->fg_light->foreground},
{{18 * 8, 7 * 16}, "MHz", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 9 * 16}, "TX Adjustment Frequency", Theme::getInstance()->fg_light->foreground},
{{18 * 8, 10 * 16}, "MHz", Theme::getInstance()->fg_light->foreground},
};
OptionsField opt_rx_correction_mode{
@@ -512,14 +512,14 @@ class SetAudioView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Controls the volume of the", Color::light_grey()},
{{1 * 8, 2 * 16}, "tone when transmitting in", Color::light_grey()},
{{1 * 8, 3 * 16}, "Soundboard or Mic apps:", Color::light_grey()},
{{2 * 8, 5 * 16}, "Tone key mix: %", Color::light_grey()},
{{1 * 8, 8 * 16}, "Controls whether apps should", Color::light_grey()},
{{1 * 8, 9 * 16}, "beep on speaker & headphone", Color::light_grey()},
{{1 * 8, 10 * 16}, "when a packet is received", Color::light_grey()},
{{1 * 8, 11 * 16}, "(not all apps support this):", Color::light_grey()},
{{1 * 8, 1 * 16}, "Controls the volume of the", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "tone when transmitting in", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "Soundboard or Mic apps:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 5 * 16}, "Tone key mix: %", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 8 * 16}, "Controls whether apps should", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 9 * 16}, "beep on speaker & headphone", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 10 * 16}, "when a packet is received", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 11 * 16}, "(not all apps support this):", Theme::getInstance()->fg_light->foreground},
};
NumberField field_tone_mix{
@@ -554,8 +554,8 @@ class SetQRCodeView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Change the size of the QR", Color::light_grey()},
{{1 * 8, 2 * 16}, "code shown in Radiosonde.", Color::light_grey()},
{{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{
@@ -586,14 +586,14 @@ class SetEncoderDialView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Adjusts sensitivity to dial", Color::light_grey()},
{{1 * 8, 2 * 16}, "rotation position (number of", Color::light_grey()},
{{1 * 8, 3 * 16}, "steps per full rotation):", Color::light_grey()},
{{2 * 8, 5 * 16}, "Dial sensitivity:", Color::light_grey()},
{{1 * 8, 8 * 16}, "Adjusts sensitivity to dial", Color::light_grey()},
{{1 * 8, 9 * 16}, "rotation rate (default 1", Color::light_grey()},
{{1 * 8, 10 * 16}, "means no rate dependency):", Color::light_grey()},
{{3 * 8, 12 * 16}, "Rate multiplier:", Color::light_grey()},
{{1 * 8, 1 * 16}, "Adjusts sensitivity to dial", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "rotation position (number of", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "steps per full rotation):", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 5 * 16}, "Dial sensitivity:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 8 * 16}, "Adjusts sensitivity to dial", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 9 * 16}, "rotation rate (default 1", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 10 * 16}, "means no rate dependency):", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 12 * 16}, "Rate multiplier:", Theme::getInstance()->fg_light->foreground},
};
OptionsField field_encoder_dial_sensitivity{
@@ -630,9 +630,9 @@ class SetPersistentMemoryView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Save persistent memory on SD", Color::light_grey()},
{{1 * 8, 2 * 16}, "card. Needed when device has", Color::light_grey()},
{{1 * 8, 3 * 16}, "dead/missing coin battery.", Color::light_grey()},
{{1 * 8, 1 * 16}, "Save persistent memory on SD", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "card. Needed when device has", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "dead/missing coin battery.", Theme::getInstance()->fg_light->foreground},
};
Text text_pmem_status{
@@ -672,7 +672,7 @@ class AppSettingsView : public View {
NavigationView& nav_;
Labels labels{
{{0, 4}, "Select file to edit:", Color::white()}};
{{0, 4}, "Select file to edit:", Theme::getInstance()->bg_darkest->foreground}};
MenuView menu_view{
{0, 2 * 8, 240, 26 * 8},
@@ -689,9 +689,9 @@ class SetConfigModeView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Controls whether firmware", Color::light_grey()},
{{1 * 8, 2 * 16}, "will enter Config Mode", Color::light_grey()},
{{1 * 8, 3 * 16}, "after a boot failure.", Color::light_grey()},
{{1 * 8, 1 * 16}, "Controls whether firmware", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "will enter Config Mode", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "after a boot failure.", Theme::getInstance()->fg_light->foreground},
};
Checkbox checkbox_config_mode_enabled{
@@ -721,10 +721,10 @@ class SetFakeBrightnessView : public View {
private:
Labels labels{
{{1 * 8, 1 * 16}, "Limits screen brightness", Color::light_grey()},
{{1 * 8, 2 * 16}, "(has a small performance", Color::light_grey()},
{{1 * 8, 3 * 16}, "impact when enabled).", Color::light_grey()},
{{2 * 8, 8 * 16}, "Brightness:", Color::light_grey()},
{{1 * 8, 1 * 16}, "Limits screen brightness", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "(has a small performance", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "impact when enabled).", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 8 * 16}, "Brightness:", Theme::getInstance()->fg_light->foreground},
};
OptionsField field_fake_brightness{
@@ -761,10 +761,10 @@ class SetMenuColorView : public View {
void paint_sample();
Labels labels{
{{3 * 8, 1 * 16}, "Menu Button Color Scheme", Color::light_grey()},
{{2 * 8, 8 * 16}, "Red Level:", Color::light_grey()},
{{2 * 8, 9 * 16}, "Green Level:", Color::light_grey()},
{{2 * 8, 10 * 16}, "Blue Level:", Color::light_grey()},
{{3 * 8, 1 * 16}, "Menu Button Color Scheme", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 8 * 16}, "Red Level:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 9 * 16}, "Green Level:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 10 * 16}, "Blue Level:", Theme::getInstance()->fg_light->foreground},
};
NewButton button_sample{
@@ -830,8 +830,8 @@ class SetAutostartView : public View {
"nav"sv,
{{"autostart_app"sv, &autostart_app}}};
Labels labels{
{{1 * 8, 1 * 16}, "Select app to start on boot", Color::light_grey()},
{{2 * 8, 2 * 16}, "(an SD Card is required)", Color::light_grey()}};
{{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},
@@ -848,6 +848,46 @@ class SetAutostartView : public View {
};
};
class SetThemeView : public View {
public:
SetThemeView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Theme"; };
private:
int32_t selected = 0;
Labels labels{
{{1 * 8, 1 * 16}, "Select a theme.", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "Restart PP to fully apply!", Theme::getInstance()->fg_light->foreground}};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
OptionsField options{
{8 * 8, 4 * 16},
30,
{
{"Default - Grey", 0},
{"Yellow", 1},
{"Aqua", 2},
{"Green", 3},
{"Red", 4},
}};
Checkbox checkbox_menuset{
{2 * 8, 6 * 16},
23,
"Set Menu color too"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
};
class SettingsMenuView : public BtnGridView {
public:
SettingsMenuView(NavigationView& nav);
+7 -7
View File
@@ -57,16 +57,16 @@ void SIGFRXView::paint(Painter& painter) {
uint8_t i, xp;
// portapack::display.drawBMP({0, 302-160}, fox_bmp);
portapack::display.fill_rectangle({0, 16, 240, 160 - 16}, ui::Color::white());
portapack::display.fill_rectangle({0, 16, 240, 160 - 16}, Theme::getInstance()->bg_darkest->foreground);
for (i = 0; i < 6; i++) {
xp = sigfrx_marks[i * 3];
painter.draw_string({(ui::Coord)sigfrx_marks[(i * 3) + 1], 144 - 20}, style_white, to_string_dec_uint(sigfrx_marks[(i * 3) + 2]));
portapack::display.draw_line({xp, 144 - 4}, {xp, 144}, ui::Color::black());
portapack::display.draw_line({xp, 144 - 4}, {xp, 144}, Theme::getInstance()->bg_darkest->background);
}
}
void SIGFRXView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
portapack::display.fill_rectangle({0, 144, 240, 4}, ui::Color::white());
portapack::display.fill_rectangle({0, 144, 240, 4}, Theme::getInstance()->bg_darkest->foreground);
uint8_t xmax = 0, imax = 0;
size_t i;
@@ -97,7 +97,7 @@ void SIGFRXView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
last_channel = imax;
portapack::display.fill_rectangle({(ui::Coord)(imax - 2), 144, 4, 4}, ui::Color::red());
portapack::display.fill_rectangle({(ui::Coord)(imax - 2), 144, 4, 4}, Theme::getInstance()->fg_red->foreground);
}
void SIGFRXView::on_show() {
@@ -129,9 +129,9 @@ SIGFRXView::SIGFRXView(
&text_data,
&button_exit});
text_type.set_style(&Styles::bg_white);
text_channel.set_style(&Styles::bg_white);
text_data.set_style(&Styles::bg_white);
text_type.set_style(Theme::getInstance()->bg_lightest);
text_channel.set_style(Theme::getInstance()->bg_lightest);
text_data.set_style(Theme::getInstance()->bg_lightest);
button_exit.on_select = [&nav](Button&) {
nav.pop();
-1
View File
@@ -24,7 +24,6 @@
#include "ui_widget.hpp"
#include "ui_painter.hpp"
#include "ui_menu.hpp"
#include "ui_styles.hpp"
#include "ui_navigation.hpp"
#include "clock_manager.hpp"
#include "message.hpp"
+6 -6
View File
@@ -72,15 +72,15 @@ class SigGenView : public View {
bool auto_update{false};
Labels labels{
{{3 * 8, 4 + 10}, "Shape:", Color::light_grey()},
{{6 * 8, 7 * 8}, "Tone: Hz", Color::light_grey()},
{{22 * 8, 15 * 8 + 4}, "s.", Color::light_grey()},
{{8 * 8, 20 * 8}, "Modulation: FM", Color::light_grey()}};
{{3 * 8, 4 + 10}, "Shape:", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 7 * 8}, "Tone: Hz", Theme::getInstance()->fg_light->foreground},
{{22 * 8, 15 * 8 + 4}, "s.", Theme::getInstance()->fg_light->foreground},
{{8 * 8, 20 * 8}, "Modulation: FM", Theme::getInstance()->fg_light->foreground}};
ImageOptionsField options_shape{
{10 * 8, 4, 32, 32},
Color::white(),
Color::black(),
Theme::getInstance()->bg_darkest->foreground,
Theme::getInstance()->bg_darkest->background,
{{&bitmap_sig_cw, 0},
{&bitmap_sig_sine, 1},
{&bitmap_sig_tri, 2},
+7 -7
View File
@@ -94,14 +94,14 @@ class SondeView : public View {
// AudioOutput audio_output { };
Labels labels{
{{4 * 8, 2 * 16}, "Type:", Color::light_grey()},
{{6 * 8, 3 * 16}, "ID:", Color::light_grey()},
{{0 * 8, 4 * 16}, "DateTime:", Color::light_grey()},
{{4 * 8, 2 * 16}, "Type:", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 3 * 16}, "ID:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 4 * 16}, "DateTime:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 5 * 16}, "Vbatt:", Color::light_grey()},
{{3 * 8, 6 * 16}, "Frame:", Color::light_grey()},
{{4 * 8, 7 * 16}, "Temp:", Color::light_grey()},
{{0 * 8, 8 * 16}, "Humidity:", Color::light_grey()}};
{{3 * 8, 5 * 16}, "Vbatt:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 6 * 16}, "Frame:", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 7 * 16}, "Temp:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Humidity:", Theme::getInstance()->fg_light->foreground}};
RxFrequencyField field_frequency{
{0 * 8, 0 * 8},
+4 -4
View File
@@ -48,12 +48,12 @@ void ScreenshotViewer::paint(Painter& painter) {
painter.fill_rectangle({0, 0, screen_width, screen_height}, Color::black());
auto show_invalid = [&]() {
painter.draw_string({10, 160}, Styles::white, "Not a valid screenshot.");
painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, "Not a valid screenshot.");
};
auto error = file.open(path_);
if (error) {
painter.draw_string({10, 160}, Styles::white, error->what());
painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, error->what());
return;
}
@@ -120,13 +120,13 @@ void SplashViewer::paint(Painter& painter) {
painter.fill_rectangle({0, 0, screen_width, screen_height}, Color::black());
if (!portapack::display.drawBMP2({0, 0}, path_)) {
painter.draw_string({10, 160}, Styles::white, "Not a valid splash image.");
painter.draw_string({10, 160}, *Theme::getInstance()->bg_darkest, "Not a valid splash image.");
return;
}
// Show option to set splash screen if it's not already the splash screen
if (!path_iequal(path_, splash_dot_bmp)) {
painter.draw_string({0, 0}, Styles::white, "*RIGHT BUTTON UPDATES SPLASH*");
painter.draw_string({0, 0}, *Theme::getInstance()->bg_darkest, "*RIGHT BUTTON UPDATES SPLASH*");
valid_image = true;
}
}
@@ -26,7 +26,6 @@
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_painter.hpp"
#include "ui_styles.hpp"
#include "ui_widget.hpp"
#include "file.hpp"
+2 -2
View File
@@ -80,8 +80,8 @@ class SSTVTXView : public View {
void prepare_scanline();
Labels labels{
{{1 * 8, 1 * 8}, "File:", Color::light_grey()},
{{1 * 8, 3 * 8}, "Mode:", Color::light_grey()}};
{{1 * 8, 1 * 8}, "File:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 8}, "Mode:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_bitmaps{
{6 * 8, 1 * 8},
+480 -5
View File
@@ -32,12 +32,15 @@ using namespace ui;
namespace ui {
void SubGhzDRecentEntryDetailView::update_data() {
// process protocol data
parseProtocol();
// set text elements
text_type.set(SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry_.sensorType));
text_id.set("0x" + to_string_hex(entry_.serial));
text_id.set("0x" + to_string_hex(serial));
if (entry_.bits > 0) console.writeln("Bits: " + to_string_dec_uint(entry_.bits));
if (entry_.btn != SD_NO_BTN) console.writeln("Btn: " + to_string_dec_uint(entry_.btn));
if (entry_.cnt != SD_NO_CNT) console.writeln("Cnt: " + to_string_dec_uint(entry_.cnt));
if (btn != SD_NO_BTN) console.writeln("Btn: " + to_string_dec_uint(btn));
if (cnt != SD_NO_CNT) console.writeln("Cnt: " + to_string_dec_uint(cnt));
if (entry_.data != 0) console.writeln("Data: " + to_string_hex(entry_.data));
}
@@ -103,7 +106,7 @@ void SubGhzDView::on_tick_second() {
}
void SubGhzDView::on_data(const SubGhzDDataMessage* data) {
SubGhzDRecentEntry key{data->sensorType, data->serial, data->bits, data->data, data->btn, data->cnt};
SubGhzDRecentEntry key{data->sensorType, data->data, data->bits};
auto matching_recent = find(recent, key.key());
if (matching_recent != std::end(recent)) {
// Found within. Move to front of list, increment counter.
@@ -203,6 +206,13 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) {
return "Star Line";
case FPS_X10:
return "X10";
case FPS_LEGRAND:
return "Legrand";
case FPS_SOMIFY_KEYTIS:
return "Somify Keytis";
case FPS_SOMIFY_TELIS:
return "Somify Telis";
case FPS_Invalid:
default:
return "Unknown";
@@ -224,7 +234,7 @@ void RecentEntriesTable<ui::SubGhzDRecentEntries>::draw(
line.reserve(30);
line = SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry.sensorType);
line = line + " " + to_string_hex(entry.serial);
line = line + " " + to_string_hex(entry.data << 32);
if (line.length() < 19) {
line += SubGhzDView::pad_string_with_spaces(19 - line.length());
} else {
@@ -239,4 +249,469 @@ void RecentEntriesTable<ui::SubGhzDRecentEntries>::draw(
painter.draw_string(target_rect.location(), style, line);
}
// decoder helper functions
void atomo_decrypt(uint8_t* buff) {
buff[0] = (buff[0] ^ 5) & 0x7F;
uint8_t tmpB = (-buff[0]) & 0x7F;
uint8_t bitCnt = 8;
while (bitCnt < 59) {
if ((tmpB & 0x18) && (((tmpB / 8) & 3) != 3)) {
tmpB = ((tmpB << 1) & 0xFF) | 1;
} else {
tmpB = (tmpB << 1) & 0xFF;
}
if (tmpB & 0x80) {
buff[bitCnt / 8] ^= (0x80 >> (bitCnt & 7));
}
bitCnt++;
}
}
const uint32_t came_twee_magic_numbers_xor[15] = {
0x0E0E0E00,
0x1D1D1D11,
0x2C2C2C22,
0x3B3B3B33,
0x4A4A4A44,
0x59595955,
0x68686866,
0x77777777,
0x86868688,
0x95959599,
0xA4A4A4AA,
0xB3B3B3BB,
0xC2C2C2CC,
0xD1D1D1DD,
0xE0E0E0EE,
};
// to save some byte of fw space, these will be inline. unreadeable? yes. needs a tons of free space? certanly. so sorry for this.
void SubGhzDRecentEntryDetailView::parseProtocol() {
btn = SD_NO_BTN;
cnt = SD_NO_CNT;
serial = 0;
if (entry_.sensorType == FPS_Invalid) return;
if (entry_.sensorType == FPS_BETT) {
return; // needs dip pattern output.
}
if (entry_.sensorType == FPS_AIRFORCE || entry_.sensorType == FPS_PRASTEL || entry_.sensorType == FPS_CAME) {
return; // nothing
}
if (entry_.sensorType == FPS_CAMEATOMO) {
entry_.data ^= 0xFFFFFFFFFFFFFFFF;
entry_.data <<= 4;
uint8_t pack[8] = {};
pack[0] = (entry_.data >> 56);
pack[1] = ((entry_.data >> 48) & 0xFF);
pack[2] = ((entry_.data >> 40) & 0xFF);
pack[3] = ((entry_.data >> 32) & 0xFF);
pack[4] = ((entry_.data >> 24) & 0xFF);
pack[5] = ((entry_.data >> 16) & 0xFF);
pack[6] = ((entry_.data >> 8) & 0xFF);
pack[7] = (entry_.data & 0xFF);
atomo_decrypt(pack);
// cnt_2 = pack[0];
cnt = (uint16_t)pack[1] << 8 | pack[2];
serial = (uint32_t)(pack[3]) << 24 | pack[4] << 16 | pack[5] << 8 | pack[6];
uint8_t btn_decode = (pack[7] >> 4);
if (btn_decode == 0x0) {
btn = 0x1;
} else if (btn_decode == 0x2) {
btn = 0x2;
} else if (btn_decode == 0x4) {
btn = 0x3;
} else if (btn_decode == 0x6) {
btn = 0x4;
}
return;
}
if (entry_.sensorType == FPS_CAMETWEE) {
uint8_t cnt_parcel = (uint8_t)(entry_.data & 0xF);
uint32_t data = (uint32_t)(entry_.data & 0x0FFFFFFFF);
data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]);
serial = data;
data /= 4;
btn = (data >> 4) & 0x0F;
data >>= 16;
data = (uint16_t)FProtoGeneral::subghz_protocol_blocks_reverse_key(data, 16);
cnt = data >> 6;
return;
}
if (entry_.sensorType == FPS_CHAMBCODE) {
return; // nothing
}
if (entry_.sensorType == FPS_CLEMSA) {
serial = (entry_.data >> 2) & 0xFFFF;
btn = (entry_.data & 0x03);
return;
}
if (entry_.sensorType == FPS_DOITRAND) {
cnt = (entry_.data >> 24) | ((entry_.data >> 15) & 0x1);
btn = ((entry_.data >> 18) & 0x3);
return;
}
if (entry_.sensorType == FPS_DOOYA) {
serial = (entry_.data >> 16);
if ((entry_.data >> 12) & 0x0F) {
cnt = (entry_.data >> 8) & 0x0F;
} else {
cnt = 0xff;
}
btn = entry_.data & 0xFF;
return;
}
if (entry_.sensorType == FPS_FAAC) { // stripped down a lot.
uint32_t code_fix = entry_.data >> 32;
uint32_t code_hop = entry_.data & 0xFFFFFFFF;
// uint32_t decrypt = 0;
// uint64_t man;
uint8_t data_tmp = 0;
uint8_t data_prg[8];
data_prg[0] = (code_hop & 0xFF);
data_prg[1] = ((code_hop >> 8) & 0xFF);
data_prg[2] = ((code_hop >> 16) & 0xFF);
data_prg[3] = (code_hop >> 24);
data_prg[4] = (code_fix & 0xFF);
data_prg[5] = ((code_fix >> 8) & 0xFF);
data_prg[6] = ((code_fix >> 16) & 0xFF);
data_prg[7] = (code_fix >> 24);
if (((data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00))) {
// ProgMode ON
for (uint8_t i = data_prg[1] & 0xF; i != 0; i--) {
data_tmp = data_prg[2];
data_prg[2] = data_prg[2] >> 1 | (data_prg[3] & 1) << 7;
data_prg[3] = data_prg[3] >> 1 | (data_prg[4] & 1) << 7;
data_prg[4] = data_prg[4] >> 1 | (data_prg[5] & 1) << 7;
data_prg[5] = data_prg[5] >> 1 | (data_tmp & 1) << 7;
}
data_prg[2] ^= data_prg[1];
data_prg[3] ^= data_prg[1];
data_prg[4] ^= data_prg[1];
data_prg[5] ^= data_prg[1];
seed = data_prg[5] << 24 | data_prg[4] << 16 | data_prg[3] << 8 | data_prg[2];
// uint32_t dec_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | data_prg[4];
// uint32_t dec_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | data_prg[0];
// entry_.data_2 = (uint64_t)dec_prg_1 << 32 | dec_prg_2;
cnt = data_prg[1];
} else {
if (code_fix != 0x0) {
serial = code_fix >> 4;
btn = code_fix & 0xF;
}
}
return;
}
if (entry_.sensorType == FPS_GATETX) {
uint32_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >> 8) & 0xFF) << 4 | ((code_found_reverse >> 20) & 0x0F);
btn = ((code_found_reverse >> 16) & 0x0F);
return;
}
if (entry_.sensorType == FPS_HOLTEK) {
if ((entry_.data & 0xF000000000) == 0x5000000000) {
serial = FProtoGeneral::subghz_protocol_blocks_reverse_key((entry_.data >> 16) & 0xFFFFF, 20);
uint16_t btn_ = entry_.data & 0xFFFF;
if ((btn_ & 0xf) != 0xA) {
btn = 0x1 << 4 | (btn_ & 0xF);
} else if (((btn_ >> 4) & 0xF) != 0xA) {
btn = 0x2 << 4 | ((btn_ >> 4) & 0xF);
} else if (((btn_ >> 8) & 0xF) != 0xA) {
btn = 0x3 << 4 | ((btn_ >> 8) & 0xF);
} else if (((btn_ >> 12) & 0xF) != 0xA) {
btn = 0x4 << 4 | ((btn_ >> 12) & 0xF);
} else {
btn = 0;
}
} else {
serial = 0;
btn = 0;
cnt = 0;
}
return;
}
if (entry_.sensorType == FPS_HOLTEKHT12X) {
btn = entry_.data & 0x0F;
cnt = (entry_.data >> 4) & 0xFF;
return;
}
if (entry_.sensorType == FPS_HONEYWELL) {
serial = (entry_.data >> 24) & 0xFFFFF;
btn = (entry_.data >> 16) & 0xFF; // not exactly button, but can contain btn data too.
cnt = (entry_.data >> 44) & 0xF;
/*
uint8_t contact = (entry_.databtn & 0x80) >> 7;
uint8_t tamper = (entry_.databtn & 0x40) >> 6;
uint8_t reed = (entry_.databtn & 0x20) >> 5;
uint8_t alarm = (entry_.databtn & 0x10) >> 4;
uint8_t battery_low = (entry_.databtn & 0x08) >> 3;
uint8_t heartbeat = (entry_.databtn & 0x04) >> 2;
*/
return;
}
if (entry_.sensorType == FPS_HONEYWELLWDB) {
serial = (entry_.data >> 28) & 0xFFFFF;
// enabled, when we'll have extra fields and free fw space
/* switch ((entry_.data >> 20) & 0x3) {
case 0x02:
device_type = "Doorbell";
break;
case 0x01:
device_type = "PIR-Motion";
break;
default:
device_type = "Unknown";
break;
}
switch ((entry_.data >> 16) & 0x3) {
case 0x00:
alert = "Normal";
break;
case 0x01:
case 0x02:
alert = "High";
break;
case 0x03:
alert = "Full";
break;
default:
alert = "Unknown";
break;
}
secret_knock = (uint8_t)((entry_.data >> 4) & 0x1);
relay = (uint8_t)((entry_.data >> 3) & 0x1);
lowbat = (uint8_t)((entry_.data >> 1) & 0x1);*/
return;
}
if (entry_.sensorType == FPS_HORMANN) {
btn = (entry_.data >> 8) & 0xF;
return;
}
/* if (entry_.sensorType == FPS_HORMANNBISECURE) { //fm not implemented
serial = 0;
for (uint8_t i = 1; i < 5; i++) {
serial = serial << 8 | ((uint8_t*)(&entry_.data))[i];
}
} */
if (entry_.sensorType == FPS_IDO) {
uint64_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
serial = code_fix & 0xFFFFF;
btn = (code_fix >> 20) & 0x0F;
return;
}
if (entry_.sensorType == FPS_INTERTECHNOV3) {
if (entry_.bits == 32) {
serial = (entry_.data >> 6) & 0x3FFFFFF;
if ((entry_.data >> 5) & 0x1) {
cnt = 1 << 5;
} else {
cnt = (~entry_.data & 0xF);
}
btn = (entry_.data >> 4) & 0x1;
} else if (entry_.bits == 36) {
serial = (entry_.data >> 10) & 0x3FFFFFF;
if ((entry_.data >> 9) & 0x1) {
cnt = 1 << 5;
} else {
cnt = (~(entry_.data >> 4) & 0xF);
}
btn = (entry_.data) & 0xF;
} else {
serial = 0;
cnt = 0;
btn = 0;
}
return;
}
if (entry_.sensorType == FPS_KEELOQ) {
// too many sub protocol versions, skipping. maybe in future when we'll have much more fw space
return;
}
/* fm not implemented
if (entry_.sensorType == FPS_KIA) {
serial = (uint32_t)((entry_.data >> 12) & 0x0FFFFFFF);
btn = (entry_.data >> 8) & 0x0F;
cnt = (entry_.data >> 40) & 0xFFFF;
return;
}
*/
if (entry_.sensorType == FPS_KINGGATESSTYLO4K) {
uint64_t fix = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, 53);
btn = (fix >> 17) & 0x0F;
serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF);
return;
}
if (entry_.sensorType == FPS_LEGRAND) {
return; // nothing
}
if (entry_.sensorType == FPS_LINEAR || entry_.sensorType == FPS_LINEARDELTA3) {
return; // nothing
}
if (entry_.sensorType == FPS_MAGELLAN) {
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data >> 8, 24);
serial = data_rev & 0xFFFF;
btn = (data_rev >> 16) & 0xFF;
return;
}
if (entry_.sensorType == FPS_MARANTEC) {
btn = (entry_.data >> 16) & 0xF;
serial = ((entry_.data >> 12) & 0xFFFFFF00) | ((entry_.data >> 8) & 0xFF);
return;
}
if (entry_.sensorType == FPS_MASTERCODE) {
serial = (entry_.data >> 4) & 0xFFFF;
btn = (entry_.data >> 2 & 0x03);
return;
}
if (entry_.sensorType == FPS_MEGACODE) {
if ((entry_.data >> 23) == 1) {
serial = (entry_.data >> 3) & 0xFFFF;
btn = entry_.data & 0b111;
cnt = (entry_.data >> 19) & 0b1111;
} else {
serial = 0;
btn = 0;
cnt = 0;
}
return;
}
if (entry_.sensorType == FPS_NERORADIO) {
return; // nothing
}
if (entry_.sensorType == FPS_NERO_SKETCH) {
return; // nothing
}
if (entry_.sensorType == FPS_NICEFLO || entry_.sensorType == FPS_NICEFLORS) {
return; // nothing, and can't
}
if (entry_.sensorType == FPS_PHOENIXV2) {
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits + 4);
serial = data_rev & 0xFFFFFFFF;
cnt = (data_rev >> 40) & 0xFFFF;
btn = (data_rev >> 32) & 0xF;
return;
}
if (entry_.sensorType == FPS_POWERSMART) {
btn = ((entry_.data >> 54) & 0x02) | ((entry_.data >> 40) & 0x1);
serial = ((entry_.data >> 33) & 0x3FFF00) | ((entry_.data >> 32) & 0xFF);
cnt = ((entry_.data >> 49) & 0x3F);
return;
}
if (entry_.sensorType == FPS_PRINCETON) {
serial = entry_.data >> 4;
btn = entry_.data & 0xF;
return;
}
if (entry_.sensorType == FPS_SECPLUSV1) {
uint32_t fixed = (entry_.data >> 32) & 0xFFFFFFFF;
cnt = entry_.data & 0xFFFFFFFF;
btn = fixed % 3;
// uint8_t id0 = (fixed / 3) % 3;
uint8_t id1 = (fixed / 9) % 3;
// uint16_t pin = 0;
if (id1 == 0) {
// (fixed // 3**3) % (3**7) 3^3=27 3^73=72187
serial = (fixed / 27) % 2187;
// pin = (fixed // 3**10) % (3**9) 3^10=59049 3^9=19683
// pin = (fixed / 59049) % 19683;
/* if (pin <= 9999) {
furi_string_cat_printf(output, " pin:%d", pin);
} else if (pin <= 11029) {
furi_string_cat_printf(output, " pin:enter");
} */
} else {
// id = fixed / 27;
serial = fixed / 27;
}
}
if (entry_.sensorType == FPS_SECPLUSV2) {
return; // fw space saver
}
if (entry_.sensorType == FPS_SMC5326) {
return; // dip pattern output needed. skipping
}
if (entry_.sensorType == FPS_STARLINE) {
uint64_t key = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
uint32_t key_fix = key >> 32;
serial = key_fix & 0x00FFFFFF;
btn = key_fix >> 24;
return;
}
if (entry_.sensorType == FPS_X10) {
serial = (entry_.data & 0xF0000000) >> (24 + 4);
btn = (((entry_.data & 0x07000000) >> 24) | ((entry_.data & 0xF800) >> 8));
return;
}
if (entry_.sensorType == FPS_SOMIFY_KEYTIS) {
uint64_t dataa = entry_.data ^ (entry_.data >> 8);
btn = (dataa >> 48) & 0xF;
cnt = (dataa >> 24) & 0xFFFF;
serial = dataa & 0xFFFFFF;
return;
}
if (entry_.sensorType == FPS_SOMIFY_TELIS) {
uint64_t dataa = entry_.data ^ (entry_.data >> 8);
btn = (dataa >> 44) & 0xF; // ctrl
cnt = (dataa >> 24) & 0xFFFF; // rolling code
serial = dataa & 0xFFFFFF; // address}
return;
}
}
} // namespace ui
+18 -14
View File
@@ -23,6 +23,10 @@
#ifndef __UI_SUBGHZD_H__
#define __UI_SUBGHZD_H__
#define SD_NO_SERIAL 0xFFFFFFFF
#define SD_NO_BTN 0xFF
#define SD_NO_CNT 0xFF
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
@@ -33,6 +37,7 @@
#include "recent_entries.hpp"
#include "../baseband/fprotos/subghztypes.hpp"
#include "../baseband/fprotos/fprotogeneral.hpp"
using namespace ui;
@@ -42,29 +47,20 @@ struct SubGhzDRecentEntry {
using Key = uint64_t;
static constexpr Key invalid_key = 0x0fffffff;
uint8_t sensorType = FPS_Invalid;
uint8_t btn = SD_NO_BTN;
uint32_t serial = SD_NO_SERIAL;
uint16_t bits = 0;
uint16_t age = 0; // updated on each seconds, show how long the signal was last seen
uint32_t cnt = SD_NO_CNT;
uint64_t data = 0;
SubGhzDRecentEntry() {}
SubGhzDRecentEntry(
uint8_t sensorType,
uint32_t serial,
uint16_t bits = 0,
uint64_t data = 0,
uint8_t btn = SD_NO_BTN,
uint32_t cnt = SD_NO_CNT)
uint16_t bits = 0)
: sensorType{sensorType},
btn{btn},
serial{serial},
bits{bits},
cnt{cnt},
data{data} {
}
Key key() const {
return (data ^ ((static_cast<uint64_t>(serial) << 32) | (static_cast<uint64_t>(sensorType) & 0xFF) << 0));
return (data ^ ((static_cast<uint64_t>(sensorType) & 0xFF) << 0));
}
void inc_age(int delta) {
if (UINT16_MAX - delta > age) age += delta;
@@ -149,6 +145,12 @@ class SubGhzDRecentEntryDetailView : public View {
private:
NavigationView& nav_;
SubGhzDRecentEntry entry_{};
uint32_t serial = 0;
uint8_t btn = SD_NO_BTN;
uint32_t cnt = SD_NO_CNT;
uint32_t seed = 0;
Text text_type{{0 * 8, 1 * 16, 15 * 8, 16}, "?"};
Text text_id{{6 * 8, 2 * 16, 10 * 8, 16}, "?"};
@@ -156,14 +158,16 @@ class SubGhzDRecentEntryDetailView : public View {
{0, 4 * 16, 240, screen_height - (4 * 16) - 36}};
Labels labels{
{{0 * 8, 0 * 16}, "Type:", Color::light_grey()},
{{0 * 8, 2 * 16}, "Serial: ", Color::light_grey()},
{{0 * 8, 3 * 16}, "Data:", Color::light_grey()},
{{0 * 8, 0 * 16}, "Type:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Serial: ", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Data:", Theme::getInstance()->fg_light->foreground},
};
Button button_done{
{screen_width - 96 - 4, screen_height - 32 - 12, 96, 32},
"Done"};
void parseProtocol();
};
} // namespace ui
+1 -1
View File
@@ -76,7 +76,7 @@ class TestView : public View {
bool logging{false};
Labels labels{
{{0 * 8, 1 * 16}, "Data:", Color::light_grey()}};
{{0 * 8, 1 * 16}, "Data:", Theme::getInstance()->fg_light->foreground}};
RxFrequencyField field_frequency{
{0 * 8, 0 * 8},
+5 -5
View File
@@ -339,7 +339,7 @@ void TextViewer::reset_file(FileWrapper* file) {
void TextViewer::set_font_zoom(bool zoom) {
font_zoom = zoom;
font_style = font_zoom ? &Styles::white : &Styles::white_small;
font_style = font_zoom ? Theme::getInstance()->bg_darkest : Theme::getInstance()->bg_darkest_small;
char_height = style().font.line_height();
char_width = style().font.char_width();
max_line = (uint8_t)(parent_rect().height() / char_height);
@@ -425,8 +425,8 @@ TextEditorView::TextEditorView(NavigationView& nav)
&text_size,
});
text_position.set_style(&Styles::bg_dark_blue);
text_size.set_style(&Styles::bg_dark_blue);
text_position.set_style(Theme::getInstance()->option_active);
text_size.set_style(Theme::getInstance()->option_active);
viewer.set_font_zoom(enable_zoom);
@@ -542,7 +542,7 @@ void TextEditorView::open_file(const fs::path& path) {
Painter p;
auto percent = (value * 100) / total;
auto width = (percent * screen_width) / 100;
p.draw_hline({0, 16}, width, Color::yellow());
p.draw_hline({0, 16}, width, Theme::getInstance()->fg_yellow->foreground);
});
if (!result) {
@@ -653,7 +653,7 @@ void TextEditorView::prepare_for_write() {
// TODO: This would be nice to have but it causes a stack overflow in an ISR?
// Painter p;
// p.draw_string({2, 48}, Styles::yellow, "Creating temporary file...");
// p.draw_string({2, 48}, *Theme::getInstance()->fg_yellow, "Creating temporary file...");
// Copy to temp file on write.
has_temp_file_ = true;
+11 -12
View File
@@ -26,7 +26,6 @@
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_painter.hpp"
#include "ui_styles.hpp"
#include "ui_widget.hpp"
#include "app_settings.hpp"
@@ -159,61 +158,61 @@ class TextEditorMenu : public View {
Rectangle rect_frame{
{0 * 8, 0 * 8, 23 * 8, 23 * 8},
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_home{
{1 * 8, 1 * 8, 7 * 8, 7 * 8},
"Home",
&bitmap_arrow_left,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_end{
{8 * 8, 1 * 8, 7 * 8, 7 * 8},
"End",
&bitmap_arrow_right,
Color::dark_grey()};
Theme::getInstance()->fg_dark->foreground};
NewButton button_zoom{
{15 * 8, 1 * 8, 7 * 8, 7 * 8},
"Zoom",
&bitmap_icon_search,
Color::orange()};
Theme::getInstance()->fg_orange->foreground};
NewButton button_delline{
{1 * 8, 8 * 8, 7 * 8, 7 * 8},
"-Line",
&bitmap_icon_delete,
Color::dark_red()};
Theme::getInstance()->fg_red->foreground};
NewButton button_edit{
{8 * 8, 8 * 8, 7 * 8, 7 * 8},
"Edit",
&bitmap_icon_rename,
Color::dark_blue()};
Theme::getInstance()->fg_blue->foreground};
NewButton button_addline{
{15 * 8, 8 * 8, 7 * 8, 7 * 8},
"+Line",
&bitmap_icon_scanner,
Color::dark_blue()};
Theme::getInstance()->fg_blue->foreground};
NewButton button_open{
{1 * 8, 15 * 8, 7 * 8, 7 * 8},
"Open",
&bitmap_icon_load,
Color::green()};
Theme::getInstance()->fg_green->foreground};
NewButton button_save{
{8 * 8, 15 * 8, 7 * 8, 7 * 8},
"Save",
&bitmap_icon_save,
Color::green()};
Theme::getInstance()->fg_green->foreground};
NewButton button_exit{
{15 * 8, 15 * 8, 7 * 8, 7 * 8},
"Exit",
&bitmap_icon_previous,
Color::dark_red()};
Theme::getInstance()->fg_red->foreground};
};
/* View viewing and minor edits on a text file. */
@@ -269,7 +268,7 @@ class TextEditorView : public View {
{26 * 8, 34 * 8, 4 * 8, 4 * 8},
{},
&bitmap_icon_controls,
Color::dark_grey(),
Theme::getInstance()->bg_dark->background,
/*vcenter*/ true};
Text text_position{
+1 -1
View File
@@ -39,7 +39,7 @@ class ToneSearchView : public View {
NavigationView& nav_;
Labels labels{
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Color::light_grey()}};
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Theme::getInstance()->fg_light->foreground}};
LNAGainField field_lna{
{4 * 8, 0 * 16}};
+2 -2
View File
@@ -184,8 +184,8 @@ class TouchTunesView : public View {
{{23 * 8, 29 * 8}, "-"}}};
Labels labels{
{{2 * 8, 1 * 8}, "PIN:", Color::light_grey()},
{{13 * 8 + 4, 27 * 8}, "VOL1 VOL2 VOL3", Color::light_grey()}};
{{2 * 8, 1 * 8}, "PIN:", Theme::getInstance()->fg_light->foreground},
{{13 * 8 + 4, 27 * 8}, "VOL1 VOL2 VOL3", Theme::getInstance()->fg_light->foreground}};
std::array<Button, 32> buttons{};
+6 -6
View File
@@ -64,10 +64,10 @@ void ViewWavView::refresh_waveform() {
// Window
uint64_t w_start = (position * 240) / wav_reader->sample_count();
uint64_t w_width = (scale * 240) / (wav_reader->sample_count() / 240);
display.fill_rectangle({0, 10 * 16 + 1, 240, 16}, Color::black());
display.fill_rectangle({(Coord)w_start, 21 * 8, (Dim)w_width + 1, 8}, Color::white());
display.draw_line({0, 10 * 16 + 1}, {(Coord)w_start, 21 * 8}, Color::white());
display.draw_line({239, 10 * 16 + 1}, {(Coord)(w_start + w_width), 21 * 8}, Color::white());
display.fill_rectangle({0, 10 * 16 + 1, 240, 16}, Theme::getInstance()->bg_darkest->background);
display.fill_rectangle({(Coord)w_start, 21 * 8, (Dim)w_width + 1, 8}, Theme::getInstance()->bg_darkest->foreground);
display.draw_line({0, 10 * 16 + 1}, {(Coord)w_start, 21 * 8}, Theme::getInstance()->bg_darkest->foreground);
display.draw_line({239, 10 * 16 + 1}, {(Coord)(w_start + w_width), 21 * 8}, Theme::getInstance()->bg_darkest->foreground);
}
void ViewWavView::refresh_measurements() {
@@ -81,8 +81,8 @@ void ViewWavView::refresh_measurements() {
void ViewWavView::paint(Painter& painter) {
// Waveform limits
painter.draw_hline({0, 6 * 16 - 1}, 240, Color::grey());
painter.draw_hline({0, 10 * 16}, 240, Color::grey());
painter.draw_hline({0, 6 * 16 - 1}, 240, Theme::getInstance()->bg_medium->background);
painter.draw_hline({0, 10 * 16}, 240, Theme::getInstance()->bg_medium->background);
// Overall amplitude view, 0~127 to 0~255 color index
for (size_t i = 0; i < 240; i++)
+13 -13
View File
@@ -81,16 +81,16 @@ class ViewWavView : public View {
bool waveform_update_needed{false};
Labels labels{
{{0 * 8, 0 * 16}, "File:", Color::light_grey()},
{{2 * 8, 1 * 16}, "-bit mono", Color::light_grey()},
{{0 * 8, 2 * 16}, "Title:", Color::light_grey()},
{{0 * 8, 3 * 16}, "Duration:", Color::light_grey()},
{{0 * 8, 12 * 16}, "Position: . s Scale:", Color::light_grey()},
{{0 * 8, 13 * 16}, " Sample:", Color::light_grey()},
{{0 * 8, 14 * 16}, "Cursor A:", Color::dark_cyan()},
{{0 * 8, 15 * 16}, "Cursor B:", Color::dark_magenta()},
{{0 * 8, 16 * 16}, "Delta:", Color::light_grey()},
{{24 * 8, 18 * 16}, "Vol:", Color::light_grey()}};
{{0 * 8, 0 * 16}, "File:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 1 * 16}, "-bit mono", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Title:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Duration:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 12 * 16}, "Position: . s Scale:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, " Sample:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 14 * 16}, "Cursor A:", Theme::getInstance()->fg_darkcyan->foreground},
{{0 * 8, 15 * 16}, "Cursor B:", Theme::getInstance()->fg_magenta->foreground},
{{0 * 8, 16 * 16}, "Delta:", Theme::getInstance()->fg_light->foreground},
{{24 * 8, 18 * 16}, "Vol:", Theme::getInstance()->fg_light->foreground}};
Text text_filename{
{5 * 8, 0 * 16, 18 * 8, 16},
@@ -113,8 +113,8 @@ class ViewWavView : public View {
ImageButton button_play{
{24 * 8, 17 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Color::green(),
Color::black()};
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
AudioVolumeField field_volume{
{28 * 8, 18 * 16}};
@@ -124,7 +124,7 @@ class ViewWavView : public View {
240,
0,
false,
Color::white()};
Theme::getInstance()->bg_darkest->foreground};
ProgressBar progressbar{
{0 * 8, 11 * 16, 30 * 8, 4}};
@@ -203,7 +203,12 @@ const char* WeatherView::getWeatherSensorTypeName(FPROTO_WEATHER_SENSOR type) {
return "Wendox W6726";
case FPW_Acurite986:
return "Acurite986";
case FPW_KEDSUM:
return "Kedsum";
case FPW_Acurite5in1:
return "Acurite5in1";
case FPW_EmosE601x:
return "EmosE601x";
case FPW_Invalid:
default:
return "Unknown";
@@ -178,14 +178,14 @@ class WeatherRecentEntryDetailView : public View {
Text text_age{{10 * 8, 7 * 16, 10 * 8, 16}, "?"};
Labels labels{
{{0 * 8, 0 * 16}, "Weather Station", Color::light_grey()},
{{0 * 8, 1 * 16}, "Type:", Color::light_grey()},
{{0 * 8, 2 * 16}, "Id: ", Color::light_grey()},
{{0 * 8, 3 * 16}, "Temp:", Color::light_grey()},
{{0 * 8, 4 * 16}, "Humidity:", Color::light_grey()},
{{0 * 8, 5 * 16}, "Channel:", Color::light_grey()},
{{0 * 8, 6 * 16}, "Battery:", Color::light_grey()},
{{0 * 8, 7 * 16}, "Age:", Color::light_grey()},
{{0 * 8, 0 * 16}, "Weather Station", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 1 * 16}, "Type:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Id: ", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Temp:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 4 * 16}, "Humidity:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Channel:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 6 * 16}, "Battery:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 7 * 16}, "Age:", Theme::getInstance()->fg_light->foreground},
};
Button button_done{
+4 -4
View File
@@ -55,10 +55,10 @@ class WhipCalcView : public View {
void add_default_antenna();
Labels labels{
{{2 * 8, 1 * 16}, "Frequency:", Color::light_grey()},
{{7 * 8, 2 * 16}, "Wave:", Color::light_grey()},
{{5 * 8, 3 * 16}, "Metric:", Color::light_grey()},
{{3 * 8, 4 * 16}, "Imperial:", Color::light_grey()}};
{{2 * 8, 1 * 16}, "Frequency:", Theme::getInstance()->fg_light->foreground},
{{7 * 8, 2 * 16}, "Wave:", Theme::getInstance()->fg_light->foreground},
{{5 * 8, 3 * 16}, "Metric:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 4 * 16}, "Imperial:", Theme::getInstance()->fg_light->foreground}};
TxFrequencyField field_frequency{
{13 * 8, 1 * 16},
+20 -21
View File
@@ -30,7 +30,6 @@
#include "log_file.hpp"
#include "portapack.hpp"
#include "string_format.hpp"
#include "ui_styles.hpp"
#include "irq_controls.hpp"
#include "file_path.hpp"
@@ -64,27 +63,27 @@ void draw_guru_meditation_header(uint8_t source, const char* hint) {
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},
Color::red());
Theme::getInstance()->fg_red->foreground);
constexpr int border = 8;
painter.fill_rectangle(
{border, border, portapack::display.width() - (border * 2), portapack::display.height() - (border * 2)},
Color::black());
Theme::getInstance()->fg_red->background);
// NOTE: in situations like a hard fault it seems not possible to write strings longer than 16 characters.
painter.draw_string({48, 24}, Styles::white, "M? Guru");
painter.draw_string({48 + 8 * 8, 24}, Styles::white, "Meditation");
painter.draw_string({48, 24}, *Theme::getInstance()->bg_darkest, "M? Guru");
painter.draw_string({48 + 8 * 8, 24}, *Theme::getInstance()->bg_darkest, "Meditation");
if (source == CORTEX_M0) {
painter.draw_string({48 + 8, 24}, Styles::white, "0");
painter.draw_string({24, 320 - 32}, Styles::white, "Press DFU for Stack Dump");
painter.draw_string({48 + 8, 24}, *Theme::getInstance()->bg_darkest, "0");
painter.draw_string({24, 320 - 32}, *Theme::getInstance()->bg_darkest, "Press DFU for Stack Dump");
}
if (source == CORTEX_M4)
painter.draw_string({48 + 8, 24}, Styles::white, "4");
painter.draw_string({48 + 8, 24}, *Theme::getInstance()->bg_darkest, "4");
painter.draw_string({15, 55}, Styles::white, "Hint: ");
painter.draw_string({15 + 8 * 8, 55}, Styles::white, hint);
painter.draw_string({15, 55}, *Theme::getInstance()->bg_darkest, "Hint: ");
painter.draw_string({15 + 8 * 8, 55}, *Theme::getInstance()->bg_darkest, hint);
}
void draw_guru_meditation(uint8_t source, const char* hint) {
@@ -130,8 +129,8 @@ void draw_guru_meditation(uint8_t source, const char* hint, struct extctx* ctxp,
void draw_line(int32_t y_offset, const char* label, regarm_t value) {
Painter painter;
painter.draw_string({15, y_offset}, Styles::white, label);
painter.draw_string({15 + 8 * 8, y_offset}, Styles::white, to_string_hex((uint32_t)value, 8));
painter.draw_string({15, y_offset}, *Theme::getInstance()->bg_darkest, label);
painter.draw_string({15 + 8 * 8, y_offset}, *Theme::getInstance()->bg_darkest, to_string_hex((uint32_t)value, 8));
}
void runtime_error(uint8_t source) {
@@ -172,7 +171,7 @@ void draw_stack_dump() {
if (clear_rect) {
painter.fill_rectangle(
{border, border, portapack::display.width() - (border * 2), portapack::display.height() - (border * 2)},
Color::black());
Theme::getInstance()->fg_red->background);
x = y = border;
clear_rect = false;
}
@@ -186,11 +185,11 @@ void draw_stack_dump() {
auto stack_space_left = p - &__process_stack_base__;
// NOTE: in situations like a hard fault it seems not possible to write strings longer than 16 characters.
painter.draw_string({x, y}, Styles::white_small, to_string_hex((uint32_t)&__process_stack_base__, 8));
painter.draw_string({x, y}, *Theme::getInstance()->bg_darkest_small, to_string_hex((uint32_t)&__process_stack_base__, 8));
x += 8 * 5;
painter.draw_string({x, y}, Styles::white_small, " M0 STACK free=");
painter.draw_string({x, y}, *Theme::getInstance()->bg_darkest_small, " M0 STACK free=");
x += 15 * 5;
painter.draw_string({x, y}, Styles::white_small, to_string_dec_uint(stack_space_left));
painter.draw_string({x, y}, *Theme::getInstance()->bg_darkest_small, to_string_dec_uint(stack_space_left));
x = border;
y += 8;
@@ -202,13 +201,13 @@ void draw_stack_dump() {
while ((p < &__process_stack_end__) && (y < portapack::display.height() - border - 8)) {
// show address if start of line
if (n++ == 0) {
painter.draw_string({x, y}, Styles::white_small, to_string_hex((uint32_t)p, 8) + ":");
painter.draw_string({x, y}, *Theme::getInstance()->bg_darkest_small, to_string_hex((uint32_t)p, 8) + ":");
x += 9 * 5 - 2; // note: saving 2 pixels here to prevent reaching right border
}
// show stack word -- highlight if a possible code address (low bit will be set too for !thumb) or actual fault address
bool code_addr = (*p > 0x1400) && (*p < 0x80000) && (((*p) & 0x1) == 0x1); // approximate address range of code .text region in ROM
Style style = (fault_address && *p == fault_address) ? Styles::bg_yellow_small : (code_addr ? Styles::bg_white_small : Styles::white_small);
Style style = (fault_address && *p == fault_address) ? *Theme::getInstance()->bg_important_small : (code_addr ? *Theme::getInstance()->bg_lightest_small : *Theme::getInstance()->bg_darkest_small);
painter.draw_string({x, y}, style, " " + to_string_hex(*p, 8));
x += 9 * 5;
@@ -229,7 +228,7 @@ void draw_stack_dump() {
while (swizzled_switches() & ((1 << (int)Switch::Right) | (1 << (int)Switch::Left) | (1 << (int)Switch::Down) | (1 << (int)Switch::Up) | (1 << (int)Switch::Sel) | (1 << (int)Switch::Dfu)))
;
painter.draw_string({border, portapack::display.height() - border - 8}, Styles::white_small, "Use UP/DOWN key");
painter.draw_string({border, portapack::display.height() - border - 8}, *Theme::getInstance()->bg_darkest_small, "Use UP/DOWN key");
// Wait for button press.
while (1) {
@@ -282,7 +281,7 @@ bool memory_dump(uint32_t* addr_start, uint32_t num_words, bool stack_flag) {
if (!error)
error = dump_file.create(filename) != 0;
if (error) {
painter.draw_string({16, 320 - 32}, ui::Styles::red, "ERROR DUMPING " + filename.filename().string() + "!");
painter.draw_string({16, 320 - 32}, *ui::Theme::getInstance()->error_dark, "ERROR DUMPING " + filename.filename().string() + "!");
return false;
}
@@ -318,7 +317,7 @@ bool memory_dump(uint32_t* addr_start, uint32_t num_words, bool stack_flag) {
}
}
painter.draw_string({0, 320 - 16}, ui::Styles::green, filename.filename().string() + " dumped!");
painter.draw_string({0, 320 - 16}, *ui::Theme::getInstance()->fg_green, filename.filename().string() + " dumped!");
return true;
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2023 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_adsb_tx.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::adsbtx {
void initialize_app(ui::NavigationView& nav) {
nav.push<ADSBTxView>();
}
} // namespace ui::external_app::adsbtx
extern "C" {
__attribute__((section(".external_app.app_adsbtx.application_information"), used)) application_information_t _application_information_adsbtx = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::adsbtx::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "ADSB-TX",
/*.bitmap_data = */ {
0x80,
0x01,
0xC0,
0x03,
0xC0,
0x03,
0xC0,
0x03,
0xC0,
0x03,
0xE0,
0x07,
0xF8,
0x1F,
0xFE,
0x7F,
0xFF,
0xFF,
0xFF,
0xFF,
0xC0,
0x03,
0xC0,
0x03,
0xC0,
0x03,
0xE0,
0x07,
0xF0,
0x0F,
0xF8,
0x1F,
},
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX,
/*.m4_app_tag = portapack::spi_flash::image_tag_adsbtx */ {'P', 'A', 'D', 'T'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
@@ -34,7 +34,7 @@
using namespace adsb;
using namespace portapack;
namespace ui {
namespace ui::external_app::adsbtx {
Compass::Compass(
const Point parent_pos)
@@ -49,23 +49,23 @@ void Compass::set_value(uint32_t new_value) {
display.draw_line(
center,
center + polar_to_point(value_, 28),
Color::dark_grey());
Theme::getInstance()->bg_dark->background);
display.draw_line(
center,
center + polar_to_point(new_value, 28),
Color::green());
Theme::getInstance()->fg_green->foreground);
value_ = new_value;
}
void Compass::paint(Painter&) {
display.fill_circle(screen_pos() + Point(32, 32), 32, Color::dark_grey(), Color::black());
display.fill_circle(screen_pos() + Point(32, 32), 32, Theme::getInstance()->fg_dark->foreground, Theme::getInstance()->fg_dark->background);
display.fill_rectangle({screen_pos() + Point(32 - 2, 0), {4, 4}}, Color::black()); // N
display.fill_rectangle({screen_pos() + Point(32 - 2, 64 - 4), {4, 4}}, Color::black()); // S
display.fill_rectangle({screen_pos() + Point(0, 32 - 2), {4, 4}}, Color::black()); // W
display.fill_rectangle({screen_pos() + Point(64 - 4, 32 - 2), {4, 4}}, Color::black()); // E
display.fill_rectangle({screen_pos() + Point(32 - 2, 0), {4, 4}}, Theme::getInstance()->fg_dark->background); // N
display.fill_rectangle({screen_pos() + Point(32 - 2, 64 - 4), {4, 4}}, Theme::getInstance()->fg_dark->background); // S
display.fill_rectangle({screen_pos() + Point(0, 32 - 2), {4, 4}}, Theme::getInstance()->fg_dark->background); // W
display.fill_rectangle({screen_pos() + Point(64 - 4, 32 - 2), {4, 4}}, Theme::getInstance()->fg_dark->background); // E
set_value(value_);
}
@@ -311,7 +311,8 @@ void ADSBTxView::start_tx() {
ADSBTxView::ADSBTxView(
NavigationView& nav)
: nav_{nav} {
baseband::run_image(portapack::spi_flash::image_tag_adsb_tx);
// baseband::run_image(portapack::spi_flash::image_tag_adsb_tx);
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
add_children({&tab_view,
&labels,
@@ -341,4 +342,4 @@ ADSBTxView::ADSBTxView(
};
}
} /* namespace ui */
} /* namespace ui::external_app::adsbtx */
@@ -34,7 +34,7 @@
using namespace adsb;
namespace ui {
namespace ui::external_app::adsbtx {
class Compass : public Widget {
public:
@@ -76,7 +76,7 @@ class ADSBCallsignView : public OptionTabView {
std::string callsign = "TEST1234";
Labels labels_callsign{
{{2 * 8, 5 * 8}, "Callsign:", Color::light_grey()}};
{{2 * 8, 5 * 8}, "Callsign:", Theme::getInstance()->fg_light->foreground}};
Button button_callsign{
{12 * 8, 2 * 16, 10 * 8, 2 * 16},
@@ -91,10 +91,10 @@ class ADSBSpeedView : public OptionTabView {
private:
Labels labels_speed{
{{1 * 8, 6 * 16}, "Speed: kn Bearing: *", Color::light_grey()}};
{{1 * 8, 6 * 16}, "Speed: kn Bearing: *", Theme::getInstance()->fg_light->foreground}};
Labels labels_vert_rate{
{{1 * 8, 8 * 16}, "Vert. rate: ft/min, (+/-)", Color::light_grey()}};
{{1 * 8, 8 * 16}, "Vert. rate: ft/min, (+/-)", Theme::getInstance()->fg_light->foreground}};
Compass compass{
{21 * 8, 2 * 16}};
@@ -131,7 +131,7 @@ class ADSBSquawkView : public OptionTabView {
private:
Labels labels_squawk{
{{2 * 8, 2 * 16}, "Squawk:", Color::light_grey()}};
{{2 * 8, 2 * 16}, "Squawk:", Theme::getInstance()->fg_light->foreground}};
SymField field_squawk{
{10 * 8, 2 * 16},
@@ -226,13 +226,13 @@ class ADSBTxView : public View {
ADSBSquawkView view_squawk{view_rect};
TabView tab_view{
{"Position", Color::cyan(), &view_position},
{"Callsign", Color::green(), &view_callsign},
{"Speed", Color::yellow(), &view_speed},
{"Squawk", Color::orange(), &view_squawk}};
{"Position", Theme::getInstance()->fg_cyan->foreground, &view_position},
{"Callsign", Theme::getInstance()->fg_green->foreground, &view_callsign},
{"Speed", Theme::getInstance()->fg_yellow->foreground, &view_speed},
{"Squawk", Theme::getInstance()->fg_orange->foreground, &view_squawk}};
Labels labels{
{{2 * 8, 4 * 8}, "ICAO24:", Color::light_grey()}};
{{2 * 8, 4 * 8}, "ICAO24:", Theme::getInstance()->fg_light->foreground}};
SymField sym_icao{
{10 * 8, 4 * 8},
@@ -251,4 +251,4 @@ class ADSBTxView : public View {
std::unique_ptr<ADSBTXThread> tx_thread{};
};
} /* namespace ui */
} // namespace ui::external_app::adsbtx
+6 -8
View File
@@ -41,8 +41,6 @@ namespace ui::external_app::analogtv {
/* AnalogTvView *******************************************************/
static const Style& style_options_group_new = Styles::bg_blue;
AnalogTvView::AnalogTvView(
NavigationView& nav)
: nav_(nav) {
@@ -140,13 +138,13 @@ void AnalogTvView::set_options_widget(std::unique_ptr<Widget> new_widget) {
options_widget = std::move(new_widget);
} else {
// TODO: Lame hack to hide options view due to my bad paint/damage algorithm.
options_widget = std::make_unique<Rectangle>(options_view_rect, style_options_group_new.background);
options_widget = std::make_unique<Rectangle>(options_view_rect, Theme::getInstance()->option_active->background);
}
add_child(options_widget.get());
}
void AnalogTvView::on_show_options_frequency() {
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, &style_options_group_new);
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, Theme::getInstance()->option_active);
widget->set_step(receiver_model.frequency_step());
widget->on_change_step = [this](rf::Frequency f) {
@@ -158,14 +156,14 @@ void AnalogTvView::on_show_options_frequency() {
};
set_options_widget(std::move(widget));
field_frequency.set_style(&style_options_group_new);
field_frequency.set_style(Theme::getInstance()->option_active);
}
void AnalogTvView::on_show_options_rf_gain() {
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, &style_options_group_new);
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, Theme::getInstance()->option_active);
set_options_widget(std::move(widget));
field_lna.set_style(&style_options_group_new);
field_lna.set_style(Theme::getInstance()->option_active);
}
void AnalogTvView::on_show_options_modulation() {
@@ -175,7 +173,7 @@ void AnalogTvView::on_show_options_modulation() {
tv.show_audio_spectrum_view(true);
set_options_widget(std::move(widget));
options_modulation.set_style(&style_options_group_new);
options_modulation.set_style(Theme::getInstance()->option_active);
}
void AnalogTvView::on_frequency_step_changed(rf::Frequency f) {
@@ -30,7 +30,6 @@
#include "ui_freq_field.hpp"
#include "ui_tv.hpp"
#include "ui_record_view.hpp"
#include "ui_styles.hpp"
#include "app_settings.hpp"
#include "radio_state.hpp"
+11 -11
View File
@@ -44,13 +44,13 @@ class AudioTestView : public View {
bool beep{false};
Labels labels{
{{7 * 8, 3 * 16}, "Audio Beep Test", Color::light_grey()},
{{0 * 8, 6 * 16}, "Sample Rate (Hz):", Color::light_grey()},
{{25 * 8, 7 * 16}, "Step:", Color::light_grey()},
{{0 * 8, 8 * 16}, "Frequency (Hz):", Color::light_grey()},
{{0 * 8, 10 * 16}, "Duration (ms):", Color::light_grey()},
{{25 * 8, 10 * 16}, "0=con", Color::light_grey()},
{{0 * 8, 12 * 16}, "Volume:", Color::light_grey()}};
{{7 * 8, 3 * 16}, "Audio Beep Test", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 6 * 16}, "Sample Rate (Hz):", Theme::getInstance()->fg_light->foreground},
{{25 * 8, 7 * 16}, "Step:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Frequency (Hz):", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "Duration (ms):", Theme::getInstance()->fg_light->foreground},
{{25 * 8, 10 * 16}, "0=con", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 12 * 16}, "Volume:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_sample_rate{
{18 * 8, 6 * 16},
@@ -90,10 +90,10 @@ class AudioTestView : public View {
{21 * 8, 14 * 16, 2 * 8, 1 * 16},
&bitmap_icon_speaker_mute,
&bitmap_icon_speaker,
Color::light_grey(),
Color::dark_grey(),
Color::green(),
Color::dark_grey()};
Theme::getInstance()->fg_light->foreground,
Theme::getInstance()->bg_dark->background,
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->bg_dark->background};
};
} /* namespace ui */
+50
View File
@@ -327,6 +327,52 @@ void BLESpamView::createNameSpamPacket() {
std::copy(res.begin(), res.end(), advertisementData);
}
char BLESpamView::randomNameChar() {
int randVal = rand() % 62; // 26 uppercase + 26 lowercase + 10 digits
if (randVal < 26) {
return 'A' + randVal; // Uppercase letters
} else if (randVal < 52) {
return 'a' + (randVal - 26); // Lowercase letters
} else {
return '0' + (randVal - 52); // Digits
}
}
void BLESpamView::createNameRandomPacket() {
char name[] = " ";
uint8_t name_len = strlen(name);
for (uint8_t i = 0; i < name_len; ++i) {
name[i] = randomNameChar();
}
uint8_t size = 12 + name_len;
uint8_t i = 0;
packet[i++] = 2; // Size
packet[i++] = 0x01; // AD Type (Flags)
packet[i++] = 0x06; // Flags
packet[i++] = name_len + 1; // Size
packet[i++] = 0x09; // AD Type (Complete Local Name)
memcpy(&packet[i], name, name_len); // Device Name
i += name_len;
packet[i++] = 3; // Size
packet[i++] = 0x02; // AD Type (Incomplete Service UUID List)
packet[i++] = 0x12; // Service UUID (Human Interface Device)
packet[i++] = 0x18; // ...
packet[i++] = 2; // Size
packet[i++] = 0x0A; // AD Type (Tx Power Level)
packet[i++] = 0x00; // 0dBm
// size, packet
std::string res = to_string_hex_array(packet, size);
memset(advertisementData, 0, sizeof(advertisementData));
std::copy(res.begin(), res.end(), advertisementData);
}
void BLESpamView::createIosPacket(bool crash = false) {
uint8_t ios_packet_sizes[18] = {0, 0, 0, 0, 0, 24, 0, 31, 0, 12, 0, 0, 20, 0, 12, 11, 11, 17};
ContinuityType type;
@@ -550,6 +596,7 @@ void BLESpamView::createAnyPacket(bool safe) {
ATK_WINDOWS,
ATK_SAMSUNG,
ATK_NAMESPAM,
ATK_NAMERANDOM,
ATK_IOS_CRASH};
ATK_TYPE attackType = type[rand() % (COUNT_OF(type) - (1 ? safe : 0))];
createPacket(attackType);
@@ -572,6 +619,9 @@ void BLESpamView::createPacket(ATK_TYPE attackType) {
case ATK_NAMESPAM:
createNameSpamPacket();
break;
case ATK_NAMERANDOM:
createNameRandomPacket();
break;
case ATK_ALL_SAFE:
createAnyPacket(true);
break;
+6 -2
View File
@@ -51,6 +51,7 @@ enum ATK_TYPE {
ATK_WINDOWS,
ATK_SAMSUNG,
ATK_NAMESPAM,
ATK_NAMERANDOM,
ATK_ALL_SAFE,
ATK_ALL
};
@@ -129,8 +130,9 @@ class BLESpamView : public View {
{"Windows", 3},
{"Samsung", 4},
{"NameSpam", 5},
{"All-Safe", 6},
{"All", 7}}};
{"NameRandom", 6},
{"All-Safe", 7},
{"All", 8}}};
bool is_running{false};
@@ -155,6 +157,7 @@ class BLESpamView : public View {
void createSamsungPacket();
void createWindowsPacket();
void createNameSpamPacket();
void createNameRandomPacket();
void createAnyPacket(bool safe);
void createPacket(ATK_TYPE attackType);
void changePacket(bool forced);
@@ -163,6 +166,7 @@ class BLESpamView : public View {
uint64_t get_freq_by_channel_number(uint8_t channel_number);
void randomizeMac();
void randomChn();
char randomNameChar();
void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len);
+2 -2
View File
@@ -65,8 +65,8 @@ class CoasterPagerView : public View {
void on_tx_progress(const uint32_t progress, const bool done);
Labels labels{
{{1 * 8, 3 * 8}, "Syscall pager TX beta", Color::light_grey()},
{{1 * 8, 8 * 8}, LanguageHelper::currentMessages[LANG_DATADP], Color::light_grey()}};
{{1 * 8, 3 * 8}, "Syscall pager TX beta", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 8 * 8}, LanguageHelper::currentMessages[LANG_DATADP], Theme::getInstance()->fg_light->foreground}};
SymField sym_data{
{7 * 8, 8 * 8},
+10
View File
@@ -80,6 +80,14 @@ set(EXTCPPSRC
#tpmsrx
external/tpmsrx/main.cpp
external/tpmsrx/tpms_app.cpp
#protoview
external/protoview/main.cpp
external/protoview/ui_protoview.cpp
#adsbtx
external/adsbtx/main.cpp
external/adsbtx/ui_adsb_tx.cpp
)
set(EXTAPPLIST
@@ -102,4 +110,6 @@ set(EXTAPPLIST
audio_test
wardrivemap
tpmsrx
protoview
adsbtx
)
+16
View File
@@ -42,6 +42,8 @@ MEMORY
ram_external_app_audio_test(rwx) : org = 0xADC10000, len = 32k
ram_external_app_wardrivemap(rwx) : org = 0xADC20000, len = 32k
ram_external_app_tpmsrx(rwx) : org = 0xADC30000, len = 32k
ram_external_app_protoview(rwx) : org = 0xADC40000, len = 32k
ram_external_app_adsbtx(rwx) : org = 0xADC50000, len = 32k
}
SECTIONS
@@ -160,4 +162,18 @@ SECTIONS
*(*ui*external_app*tpmsrx*);
} > ram_external_app_tpmsrx
.external_app_protoview : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_protoview.application_information));
*(*ui*external_app*protoview*);
} > ram_external_app_protoview
.external_app_adsbtx : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_adsbtx.application_information));
*(*ui*external_app*adsbtx*);
} > ram_external_app_adsbtx
}

Some files were not shown because too many files have changed in this diff Show More