From ced8012783e6000178658e38defcbf8b8dcb5c03 Mon Sep 17 00:00:00 2001 From: Totoo Date: Mon, 27 May 2024 21:02:52 +0200 Subject: [PATCH] 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 --- firmware/application/CMakeLists.txt | 2 +- .../application/apps/analog_audio_app.cpp | 22 +- .../application/apps/analog_audio_app.hpp | 1 - firmware/application/apps/ble_comm_app.hpp | 8 +- firmware/application/apps/ble_rx_app.hpp | 14 +- firmware/application/apps/ble_tx_app.hpp | 16 +- firmware/application/apps/capture_app.hpp | 4 +- firmware/application/apps/pocsag_app.cpp | 26 +- firmware/application/apps/pocsag_app.hpp | 9 +- firmware/application/apps/replay_app.hpp | 4 +- firmware/application/apps/soundboard_app.cpp | 2 +- firmware/application/apps/soundboard_app.hpp | 4 +- firmware/application/apps/ui_about.cpp | 4 +- firmware/application/apps/ui_about_simple.cpp | 4 +- firmware/application/apps/ui_adsb_rx.cpp | 6 +- firmware/application/apps/ui_adsb_rx.hpp | 38 +- firmware/application/apps/ui_adsb_tx.cpp | 14 +- firmware/application/apps/ui_adsb_tx.hpp | 18 +- firmware/application/apps/ui_aprs_rx.cpp | 2 +- firmware/application/apps/ui_aprs_rx.hpp | 4 +- firmware/application/apps/ui_aprs_tx.hpp | 6 +- firmware/application/apps/ui_battinfo.cpp | 1 - firmware/application/apps/ui_battinfo.hpp | 8 +- firmware/application/apps/ui_bht_tx.hpp | 24 +- .../application/apps/ui_bmp_file_viewer.hpp | 1 - firmware/application/apps/ui_debug.cpp | 61 ++- firmware/application/apps/ui_debug.hpp | 22 +- firmware/application/apps/ui_dfu_menu.cpp | 20 +- firmware/application/apps/ui_dfu_menu.hpp | 44 +- firmware/application/apps/ui_encoders.hpp | 32 +- firmware/application/apps/ui_fileman.cpp | 8 +- firmware/application/apps/ui_fileman.hpp | 36 +- .../application/apps/ui_flash_utility.cpp | 17 +- .../application/apps/ui_flash_utility.hpp | 2 +- firmware/application/apps/ui_freqman.cpp | 11 +- firmware/application/apps/ui_freqman.hpp | 32 +- firmware/application/apps/ui_fsk_rx.hpp | 7 +- firmware/application/apps/ui_iq_trim.cpp | 8 +- firmware/application/apps/ui_iq_trim.hpp | 27 +- firmware/application/apps/ui_level.cpp | 6 +- firmware/application/apps/ui_level.hpp | 5 +- .../application/apps/ui_looking_glass_app.cpp | 16 +- .../application/apps/ui_looking_glass_app.hpp | 13 +- firmware/application/apps/ui_mictx.cpp | 4 +- firmware/application/apps/ui_mictx.hpp | 42 +- firmware/application/apps/ui_modemsetup.hpp | 12 +- firmware/application/apps/ui_morse.hpp | 10 +- firmware/application/apps/ui_numbers.cpp | 3 +- firmware/application/apps/ui_numbers.hpp | 4 +- firmware/application/apps/ui_playlist.hpp | 16 +- firmware/application/apps/ui_pocsag_tx.hpp | 12 +- firmware/application/apps/ui_rds.hpp | 28 +- firmware/application/apps/ui_recon.cpp | 80 +-- firmware/application/apps/ui_recon.hpp | 11 +- .../application/apps/ui_recon_settings.cpp | 18 +- .../application/apps/ui_recon_settings.hpp | 7 +- firmware/application/apps/ui_remote.cpp | 4 +- firmware/application/apps/ui_remote.hpp | 18 +- firmware/application/apps/ui_scanner.cpp | 12 +- firmware/application/apps/ui_scanner.hpp | 13 +- firmware/application/apps/ui_script.cpp | 2 +- firmware/application/apps/ui_sd_over_usb.cpp | 6 +- firmware/application/apps/ui_sd_over_usb.hpp | 10 +- firmware/application/apps/ui_search.cpp | 18 +- firmware/application/apps/ui_search.hpp | 13 +- firmware/application/apps/ui_settings.cpp | 51 +- firmware/application/apps/ui_settings.hpp | 168 ++++--- firmware/application/apps/ui_sigfrx.cpp | 14 +- firmware/application/apps/ui_sigfrx.hpp | 1 - firmware/application/apps/ui_siggen.hpp | 12 +- firmware/application/apps/ui_sonde.hpp | 14 +- firmware/application/apps/ui_ss_viewer.cpp | 8 +- firmware/application/apps/ui_ss_viewer.hpp | 1 - firmware/application/apps/ui_sstvtx.hpp | 4 +- firmware/application/apps/ui_subghzd.hpp | 6 +- firmware/application/apps/ui_test.hpp | 2 +- firmware/application/apps/ui_text_editor.cpp | 10 +- firmware/application/apps/ui_text_editor.hpp | 23 +- firmware/application/apps/ui_tone_search.hpp | 2 +- firmware/application/apps/ui_touchtunes.hpp | 4 +- firmware/application/apps/ui_view_wav.cpp | 12 +- firmware/application/apps/ui_view_wav.hpp | 26 +- .../application/apps/ui_weatherstation.hpp | 16 +- firmware/application/apps/ui_whipcalc.hpp | 8 +- firmware/application/debug.cpp | 41 +- .../external/analogtv/analog_tv_app.cpp | 14 +- .../external/analogtv/analog_tv_app.hpp | 1 - .../external/audio_test/ui_audio_test.hpp | 22 +- .../external/coasterp/ui_coasterp.hpp | 4 +- .../external/extsensors/ui_extsensors.hpp | 6 +- .../external/font_viewer/ui_font_viewer.cpp | 5 +- .../external/gpssim/gps_sim_app.hpp | 4 +- .../application/external/jammer/ui_jammer.cpp | 14 +- .../application/external/jammer/ui_jammer.hpp | 43 +- .../application/external/keyfob/ui_keyfob.hpp | 10 +- firmware/application/external/lcr/ui_lcr.cpp | 2 +- firmware/application/external/lcr/ui_lcr.hpp | 4 +- firmware/application/external/lge/lge_app.hpp | 20 +- .../external/spainter/ui_spectrum_painter.cpp | 4 +- .../external/spainter/ui_spectrum_painter.hpp | 12 +- .../external/tetris/SPI_TFT_ILI9341.h | 2 +- .../application/external/tetris/ui_tetris.hpp | 1 - firmware/application/main.cpp | 2 + firmware/application/portapack.cpp | 10 +- firmware/application/portapack.hpp | 1 + firmware/application/recent_entries.cpp | 2 +- firmware/application/theme.cpp | 456 ++++++++++++++++++ firmware/application/theme.hpp | 103 ++++ firmware/application/ui/ui_alphanum.cpp | 6 +- firmware/application/ui/ui_alphanum.hpp | 6 +- firmware/application/ui/ui_bmpview.cpp | 2 +- firmware/application/ui/ui_bmpview.hpp | 1 - firmware/application/ui/ui_btngrid.cpp | 6 +- firmware/application/ui/ui_btngrid.hpp | 4 +- firmware/application/ui/ui_channel.cpp | 6 +- firmware/application/ui/ui_freqlist.cpp | 10 +- firmware/application/ui/ui_freqlist.hpp | 1 - firmware/application/ui/ui_geomap.cpp | 11 +- firmware/application/ui/ui_geomap.hpp | 8 +- firmware/application/ui/ui_menu.cpp | 6 +- firmware/application/ui/ui_menu.hpp | 4 +- firmware/application/ui/ui_receiver.cpp | 2 +- firmware/application/ui/ui_rssi.cpp | 10 +- firmware/application/ui/ui_spectrum.cpp | 10 +- firmware/application/ui/ui_spectrum.hpp | 4 +- firmware/application/ui/ui_styles.cpp | 123 ----- firmware/application/ui/ui_styles.hpp | 82 ---- firmware/application/ui/ui_tabview.cpp | 8 +- firmware/application/ui/ui_transmitter.cpp | 10 +- firmware/application/ui/ui_transmitter.hpp | 7 +- firmware/application/ui/ui_tv.hpp | 4 +- .../ui_external_items_menu_loader.cpp | 2 +- firmware/application/ui_navigation.cpp | 39 +- firmware/application/ui_navigation.hpp | 59 ++- firmware/application/ui_record_view.cpp | 8 +- firmware/application/ui_record_view.hpp | 14 +- .../application/ui_sd_card_status_view.cpp | 8 +- .../application/ui_sd_card_status_view.hpp | 1 + firmware/application/usb_serial_shell.cpp | 6 +- .../common/portapack_persistent_memory.cpp | 17 +- .../common/portapack_persistent_memory.hpp | 2 + firmware/common/ui_widget.cpp | 104 ++-- firmware/common/ui_widget.hpp | 12 +- 143 files changed, 1566 insertions(+), 1154 deletions(-) create mode 100644 firmware/application/theme.cpp create mode 100644 firmware/application/theme.hpp delete mode 100644 firmware/application/ui/ui_styles.cpp delete mode 100644 firmware/application/ui/ui_styles.hpp diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 117a9bbf..3b81ab54 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -225,6 +225,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 +259,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 diff --git a/firmware/application/apps/analog_audio_app.cpp b/firmware/application/apps/analog_audio_app.cpp index c055539a..1e6c11e4 100644 --- a/firmware/application/apps/analog_audio_app.cpp +++ b/firmware/application/apps/analog_audio_app.cpp @@ -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 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(options_view_rect, style_options_group.background); + options_widget = std::make_unique(options_view_rect, Theme::getInstance()->option_active->background); } add_child(options_widget.get()); } void AnalogAudioView::on_show_options_frequency() { - auto widget = std::make_unique(options_view_rect, &style_options_group); + auto widget = std::make_unique(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(options_view_rect, &style_options_group); + auto widget = std::make_unique(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(options_view_rect, &style_options_group); + widget = std::make_unique(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(nbfm_view_rect, &style_options_group); + widget = std::make_unique(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(options_view_rect, &style_options_group); + widget = std::make_unique(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(this, nbfm_view_rect, &style_options_group); + widget = std::make_unique(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) { diff --git a/firmware/application/apps/analog_audio_app.hpp b/firmware/application/apps/analog_audio_app.hpp index efe154c7..6676335e 100644 --- a/firmware/application/apps/analog_audio_app.hpp +++ b/firmware/application/apps/analog_audio_app.hpp @@ -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" diff --git a/firmware/application/apps/ble_comm_app.hpp b/firmware/application/apps/ble_comm_app.hpp index a21a03cd..246d08c0 100644 --- a/firmware/application/apps/ble_comm_app.hpp +++ b/firmware/application/apps/ble_comm_app.hpp @@ -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}, diff --git a/firmware/application/apps/ble_rx_app.hpp b/firmware/application/apps/ble_rx_app.hpp index 54560ce0..402126f3 100644 --- a/firmware/application/apps/ble_rx_app.hpp +++ b/firmware/application/apps/ble_rx_app.hpp @@ -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}, diff --git a/firmware/application/apps/ble_tx_app.hpp b/firmware/application/apps/ble_tx_app.hpp index f28e5aeb..534201b7 100644 --- a/firmware/application/apps/ble_tx_app.hpp +++ b/firmware/application/apps/ble_tx_app.hpp @@ -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}}; diff --git a/firmware/application/apps/capture_app.hpp b/firmware/application/apps/capture_app.hpp index bec009ac..f04bd1c5 100644 --- a/firmware/application/apps/capture_app.hpp +++ b/firmware/application/apps/capture_app.hpp @@ -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{ diff --git a/firmware/application/apps/pocsag_app.cpp b/firmware/application/apps/pocsag_app.cpp index 3879c8e8..d2d27933 100644 --- a/firmware/application/apps/pocsag_app.cpp +++ b/firmware/application/apps/pocsag_app.cpp @@ -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); } } diff --git a/firmware/application/apps/pocsag_app.hpp b/firmware/application/apps/pocsag_app.hpp index b03161a6..4530a9cb 100644 --- a/firmware/application/apps/pocsag_app.hpp +++ b/firmware/application/apps/pocsag_app.hpp @@ -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}, diff --git a/firmware/application/apps/replay_app.hpp b/firmware/application/apps/replay_app.hpp index 5f493b1e..716fa6cd 100644 --- a/firmware/application/apps/replay_app.hpp +++ b/firmware/application/apps/replay_app.hpp @@ -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{}; diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 65cd5e83..9a00b98c 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -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(); diff --git a/firmware/application/apps/soundboard_app.hpp b/firmware/application/apps/soundboard_app.hpp index 37d74e9d..04aeb540 100644 --- a/firmware/application/apps/soundboard_app.hpp +++ b/firmware/application/apps/soundboard_app.hpp @@ -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}, diff --git a/firmware/application/apps/ui_about.cpp b/firmware/application/apps/ui_about.cpp index 8ae7125d..681d67ec 100644 --- a/firmware/application/apps/ui_about.cpp +++ b/firmware/application/apps/ui_about.cpp @@ -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(); diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index 6e127c99..153d4d18 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -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}); } diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 90771799..8ec63ec0 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -57,15 +57,15 @@ void RecentEntriesTable::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 += diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index 46730c99..9ef42718 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -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{ diff --git a/firmware/application/apps/ui_adsb_tx.cpp b/firmware/application/apps/ui_adsb_tx.cpp index 4cc0b79a..fef22a79 100644 --- a/firmware/application/apps/ui_adsb_tx.cpp +++ b/firmware/application/apps/ui_adsb_tx.cpp @@ -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_); } diff --git a/firmware/application/apps/ui_adsb_tx.hpp b/firmware/application/apps/ui_adsb_tx.hpp index 873d1e14..ffd808bc 100644 --- a/firmware/application/apps/ui_adsb_tx.hpp +++ b/firmware/application/apps/ui_adsb_tx.hpp @@ -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}, diff --git a/firmware/application/apps/ui_aprs_rx.cpp b/firmware/application/apps/ui_aprs_rx.cpp index 42b75dcf..bdbe58ea 100644 --- a/firmware/application/apps/ui_aprs_rx.cpp +++ b/firmware/application/apps/ui_aprs_rx.cpp @@ -46,7 +46,7 @@ void RecentEntriesTable::draw( Color target_color; // auto entry_age = entry.age; - target_color = Color::green(); + target_color = Theme::getInstance()->fg_green->foreground; std::string entry_string = ""; diff --git a/firmware/application/apps/ui_aprs_rx.hpp b/firmware/application/apps/ui_aprs_rx.hpp index 3c3d8337..1bf8792e 100644 --- a/firmware/application/apps/ui_aprs_rx.hpp +++ b/firmware/application/apps/ui_aprs_rx.hpp @@ -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, diff --git a/firmware/application/apps/ui_aprs_tx.hpp b/firmware/application/apps/ui_aprs_tx.hpp index 9524cc50..1cf12310 100644 --- a/firmware/application/apps/ui_aprs_tx.hpp +++ b/firmware/application/apps/ui_aprs_tx.hpp @@ -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{ diff --git a/firmware/application/apps/ui_battinfo.cpp b/firmware/application/apps/ui_battinfo.cpp index 5f64d38b..3130f279 100644 --- a/firmware/application/apps/ui_battinfo.cpp +++ b/firmware/application/apps/ui_battinfo.cpp @@ -46,7 +46,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("-"); diff --git a/firmware/application/apps/ui_battinfo.hpp b/firmware/application/apps/ui_battinfo.hpp index 91e514c0..a64600da 100644 --- a/firmware/application/apps/ui_battinfo.hpp +++ b/firmware/application/apps/ui_battinfo.hpp @@ -53,12 +53,12 @@ class BattinfoView : public View { 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}, diff --git a/firmware/application/apps/ui_bht_tx.hpp b/firmware/application/apps/ui_bht_tx.hpp index d76c98c1..0aecd291 100644 --- a/firmware/application/apps/ui_bht_tx.hpp +++ b/firmware/application/apps/ui_bht_tx.hpp @@ -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}, diff --git a/firmware/application/apps/ui_bmp_file_viewer.hpp b/firmware/application/apps/ui_bmp_file_viewer.hpp index 5f991470..c9bd57c4 100644 --- a/firmware/application/apps/ui_bmp_file_viewer.hpp +++ b/firmware/application/apps/ui_bmp_file_viewer.hpp @@ -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" diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index 3f533e46..cb8793f6 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -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(logger.capacity()) * bar_width; @@ -292,7 +291,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 +314,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 +344,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 raw_rects{{ {64 + 1, 32 + 1, 16 - 2, 16 - 2}, // Right @@ -365,7 +364,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 +381,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 +398,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 +406,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,10 +454,10 @@ 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("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }}, - {max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, max283x]() { nav_.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }}, - {si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }}, - {audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this]() { nav_.push(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("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }}, + {max283x, Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this, max283x]() { nav_.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }}, + {si5351x, Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }}, + {audio::debug::codec_name(), Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }}, }); set_max_rows(2); // allow wider buttons } @@ -486,21 +485,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(); }}, - {"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(); }}, - //{"Memory Usage", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, - {"Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [this]() { nav_.push(); }}, - {"Pers. Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, - //{ "Radio State", ui::Color::white(), nullptr, [this](){ nav_.push(); } }, - {"Reboot", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, - {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [this]() { nav_.push(); }}, - {"Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [this]() { nav_.push(); }}, - {"Touch Test", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push(); }}, + {"Buttons Test", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_controls, [this]() { nav_.push(); }}, + {"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(); }}, + //{"Memory Usage", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push(); }}, + {"Peripherals", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals, [this]() { nav_.push(); }}, + {"Pers. Memory", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push(); }}, + //{ "Radio State", ui::Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ nav_.push(); } }, + {"Reboot", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_setup, [this]() { nav_.push(); }}, + {"SD Card", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_sdcard, [this]() { nav_.push(); }}, + {"Temperature", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_temperature, [this]() { nav_.push(); }}, + {"Touch Test", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_notepad, [this]() { nav_.push(); }}, }); for (auto const& gridItem : ExternalItemsMenuLoader::load_external_items(app_location_t::DEBUG, nav_)) { @@ -535,7 +534,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 +617,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(); } diff --git a/firmware/application/apps/ui_debug.hpp b/firmware/application/apps/ui_debug.hpp index 9665389b..9a2c0368 100644 --- a/firmware/application/apps/ui_debug.hpp +++ b/firmware/application/apps/ui_debug.hpp @@ -233,8 +233,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 +288,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 +333,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}, diff --git a/firmware/application/apps/ui_dfu_menu.cpp b/firmware/application/apps/ui_dfu_menu.cpp index 62c80773..d77d4c92 100644 --- a/firmware/application/apps/ui_dfu_menu.cpp +++ b/firmware/application/apps/ui_dfu_menu.cpp @@ -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 */ diff --git a/firmware/application/apps/ui_dfu_menu.hpp b/firmware/application/apps/ui_dfu_menu.hpp index 91e3f6ee..9bcdb48c 100644 --- a/firmware/application/apps/ui_dfu_menu.hpp +++ b/firmware/application/apps/ui_dfu_menu.hpp @@ -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}, ""}; diff --git a/firmware/application/apps/ui_encoders.hpp b/firmware/application/apps/ui_encoders.hpp index 021f4746..e1661891 100644 --- a/firmware/application/apps/ui_encoders.hpp +++ b/firmware/application/apps/ui_encoders.hpp @@ -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{ diff --git a/firmware/application/apps/ui_fileman.cpp b/firmware/application/apps/ui_fileman.cpp index a03a614c..3351cc84 100644 --- a/firmware/application/apps/ui_fileman.cpp +++ b/firmware/application/apps/ui_fileman.cpp @@ -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(); }; } diff --git a/firmware/application/apps/ui_fileman.hpp b/firmware/application/apps/ui_fileman.hpp index 0bbb5e78..e044e53e 100644 --- a/firmware/application/apps/ui_fileman.hpp +++ b/firmware/application/apps/ui_fileman.hpp @@ -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 */ diff --git a/firmware/application/apps/ui_flash_utility.cpp b/firmware/application/apps/ui_flash_utility.cpp index 43bb51be..2eb935f9 100644 --- a/firmware/application/apps/ui_flash_utility.cpp +++ b/firmware/application/apps/ui_flash_utility.cpp @@ -21,7 +21,6 @@ */ #include "ui_flash_utility.hpp" -#include "ui_styles.hpp" #include "portapack_shared_memory.hpp" #include "file_path.hpp" @@ -103,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) { @@ -135,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; @@ -154,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 OR W/R ERR"); + 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"); diff --git a/firmware/application/apps/ui_flash_utility.hpp b/firmware/application/apps/ui_flash_utility.hpp index 50a97c84..626a4ff4 100644 --- a/firmware/application/apps/ui_flash_utility.hpp +++ b/firmware/application/apps/ui_flash_utility.hpp @@ -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}, diff --git a/firmware/application/apps/ui_freqman.cpp b/firmware/application/apps/ui_freqman.cpp index b3c5db75..7b6ea5a7 100644 --- a/firmware/application/apps/ui_freqman.cpp +++ b/firmware/application/apps/ui_freqman.cpp @@ -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); } } diff --git a/firmware/application/apps/ui_freqman.hpp b/firmware/application/apps/ui_freqman.hpp index 52ecc864..5392819d 100644 --- a/firmware/application/apps/ui_freqman.hpp +++ b/firmware/application/apps/ui_freqman.hpp @@ -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{ diff --git a/firmware/application/apps/ui_fsk_rx.hpp b/firmware/application/apps/ui_fsk_rx.hpp index 6c9338ca..bcebbfb3 100644 --- a/firmware/application/apps/ui_fsk_rx.hpp +++ b/firmware/application/apps/ui_fsk_rx.hpp @@ -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{ diff --git a/firmware/application/apps/ui_iq_trim.cpp b/firmware/application/apps/ui_iq_trim.cpp index a4e5297e..44583d65 100644 --- a/firmware/application/apps/ui_iq_trim.cpp +++ b/firmware/application/apps/ui_iq_trim.cpp @@ -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(); } diff --git a/firmware/application/apps/ui_iq_trim.hpp b/firmware/application/apps/ui_iq_trim.hpp index d7e15b5a..dd990f4a 100644 --- a/firmware/application/apps/ui_iq_trim.hpp +++ b/firmware/application/apps/ui_iq_trim.hpp @@ -28,7 +28,6 @@ #include "optional.hpp" #include "ui.hpp" #include "ui_navigation.hpp" -#include "ui_styles.hpp" #include "ui_widget.hpp" #include @@ -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{ diff --git a/firmware/application/apps/ui_level.cpp b/firmware/application/apps/ui_level.cpp index 62bf6865..c8176921 100644 --- a/firmware/application/apps/ui_level.cpp +++ b/firmware/application/apps/ui_level.cpp @@ -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) { diff --git a/firmware/application/apps/ui_level.hpp b/firmware/application/apps/ui_level.hpp index 3ce79bfa..c40b89ff 100644 --- a/firmware/application/apps/ui_level.hpp +++ b/firmware/application/apps/ui_level.hpp @@ -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{ diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 903f52a4..f233eacb 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -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) + "<"); } } diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index 9d6568eb..58e2d6fe 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -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}, diff --git a/firmware/application/apps/ui_mictx.cpp b/firmware/application/apps/ui_mictx.cpp index 34066266..d5c3525d 100644 --- a/firmware/application/apps/ui_mictx.cpp +++ b/firmware/application/apps/ui_mictx.cpp @@ -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) { diff --git a/firmware/application/apps/ui_mictx.hpp b/firmware/application/apps/ui_mictx.hpp index 9b599b2b..15cc4e7a 100644 --- a/firmware/application/apps/ui_mictx.hpp +++ b/firmware/application/apps/ui_mictx.hpp @@ -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:", Theme::getInstance()->fg_light->foreground}, + {{15 * 8, 3 * 8}, "FM 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, diff --git a/firmware/application/apps/ui_modemsetup.hpp b/firmware/application/apps/ui_modemsetup.hpp index 91d73c8c..d5719b6b 100644 --- a/firmware/application/apps/ui_modemsetup.hpp +++ b/firmware/application/apps/ui_modemsetup.hpp @@ -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}, diff --git a/firmware/application/apps/ui_morse.hpp b/firmware/application/apps/ui_morse.hpp index 9f9d4d02..7630b2c7 100644 --- a/firmware/application/apps/ui_morse.hpp +++ b/firmware/application/apps/ui_morse.hpp @@ -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}, diff --git a/firmware/application/apps/ui_numbers.cpp b/firmware/application/apps/ui_numbers.cpp index d8acbc21..c85bb089 100644 --- a/firmware/application/apps/ui_numbers.cpp +++ b/firmware/application/apps/ui_numbers.cpp @@ -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()); diff --git a/firmware/application/apps/ui_numbers.hpp b/firmware/application/apps/ui_numbers.hpp index 4615d8b7..bf2cd292 100644 --- a/firmware/application/apps/ui_numbers.hpp +++ b/firmware/application/apps/ui_numbers.hpp @@ -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}, diff --git a/firmware/application/apps/ui_playlist.hpp b/firmware/application/apps/ui_playlist.hpp index ff5adf56..72b50d7b 100644 --- a/firmware/application/apps/ui_playlist.hpp +++ b/firmware/application/apps/ui_playlist.hpp @@ -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{}; diff --git a/firmware/application/apps/ui_pocsag_tx.hpp b/firmware/application/apps/ui_pocsag_tx.hpp index 634e12f9..de0240ae 100644 --- a/firmware/application/apps/ui_pocsag_tx.hpp +++ b/firmware/application/apps/ui_pocsag_tx.hpp @@ -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}, diff --git a/firmware/application/apps/ui_rds.hpp b/firmware/application/apps/ui_rds.hpp index 017d5611..aebd8deb 100644 --- a/firmware/application/apps/ui_rds.hpp +++ b/firmware/application/apps/ui_rds.hpp @@ -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{ diff --git a/firmware/application/apps/ui_recon.cpp b/firmware/application/apps/ui_recon.cpp index d3531b85..48879ca1 100644 --- a/firmware/application/apps/ui_recon.cpp +++ b/firmware/application/apps/ui_recon.cpp @@ -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(""); else button_pause.set_text(""); } 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(""); } 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(""); } } @@ -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(""); } 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(""); } @@ -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(""); // 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(""); } @@ -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); diff --git a/firmware/application/apps/ui_recon.hpp b/firmware/application/apps/ui_recon.hpp index e686c278..fa310770 100644 --- a/firmware/application/apps/ui_recon.hpp +++ b/firmware/application/apps/ui_recon.hpp @@ -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 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}}; diff --git a/firmware/application/apps/ui_recon_settings.cpp b/firmware/application/apps/ui_recon_settings.cpp index 3cfd5e42..520e1b4a 100644 --- a/firmware/application/apps/ui_recon_settings.cpp +++ b/firmware/application/apps/ui_recon_settings.cpp @@ -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()); diff --git a/firmware/application/apps/ui_recon_settings.hpp b/firmware/application/apps/ui_recon_settings.hpp index fee03164..eb5d257e 100644 --- a/firmware/application/apps/ui_recon_settings.hpp +++ b/firmware/application/apps/ui_recon_settings.hpp @@ -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}, diff --git a/firmware/application/apps/ui_remote.cpp b/firmware/application/apps/ui_remote.cpp index f2335ce6..ea4c7fd5 100644 --- a/firmware/application/apps/ui_remote.cpp +++ b/firmware/application/apps/ui_remote.cpp @@ -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); } }; diff --git a/firmware/application/apps/ui_remote.hpp b/firmware/application/apps/ui_remote.hpp index bd1aa344..548f8a14 100644 --- a/firmware/application/apps/ui_remote.hpp +++ b/firmware/application/apps/ui_remote.hpp @@ -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}, {}}; diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index fc49f664..edd0d612 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -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())); } } diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp index d6031731..4ba52bc4 100644 --- a/firmware/application/apps/ui_scanner.hpp +++ b/firmware/application/apps/ui_scanner.hpp @@ -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{ diff --git a/firmware/application/apps/ui_script.cpp b/firmware/application/apps/ui_script.cpp index a76da3df..a9717195 100644 --- a/firmware/application/apps/ui_script.cpp +++ b/firmware/application/apps/ui_script.cpp @@ -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}); diff --git a/firmware/application/apps/ui_sd_over_usb.cpp b/firmware/application/apps/ui_sd_over_usb.cpp index f21e7590..93780915 100644 --- a/firmware/application/apps/ui_sd_over_usb.cpp +++ b/firmware/application/apps/ui_sd_over_usb.cpp @@ -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); diff --git a/firmware/application/apps/ui_sd_over_usb.hpp b/firmware/application/apps/ui_sd_over_usb.hpp index 1fa8e39d..b9707693 100644 --- a/firmware/application/apps/ui_sd_over_usb.hpp +++ b/firmware/application/apps/ui_sd_over_usb.hpp @@ -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{ diff --git a/firmware/application/apps/ui_search.cpp b/firmware/application/apps/ui_search.cpp index 30bd8b8b..73fb5737 100644 --- a/firmware/application/apps/ui_search.cpp +++ b/firmware/application/apps/ui_search.cpp @@ -80,11 +80,11 @@ SearchView::SearchView( nav.push(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); } } diff --git a/firmware/application/apps/ui_search.hpp b/firmware/application/apps/ui_search.hpp index 9342422b..c7663e28 100644 --- a/firmware/application/apps/ui_search.hpp +++ b/firmware/application/apps/ui_search.hpp @@ -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> 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}}; diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index aed8f67e..221b3baf 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -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(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(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(); }}, {"Brightness", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push(); }}, {"Menu Color", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push(); }}, + {"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, {"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, }); } diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 92c0bb3d..456b8f86 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -65,14 +65,14 @@ class SetDateTimeView : public View { std::vector 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,44 @@ 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}, + }}; + + 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); diff --git a/firmware/application/apps/ui_sigfrx.cpp b/firmware/application/apps/ui_sigfrx.cpp index ebe872ae..750cf9c6 100644 --- a/firmware/application/apps/ui_sigfrx.cpp +++ b/firmware/application/apps/ui_sigfrx.cpp @@ -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(); diff --git a/firmware/application/apps/ui_sigfrx.hpp b/firmware/application/apps/ui_sigfrx.hpp index 24de2088..95b8ad83 100644 --- a/firmware/application/apps/ui_sigfrx.hpp +++ b/firmware/application/apps/ui_sigfrx.hpp @@ -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" diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index 1541426b..efd7dcea 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -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}, diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index bbf50929..242250ef 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -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}, diff --git a/firmware/application/apps/ui_ss_viewer.cpp b/firmware/application/apps/ui_ss_viewer.cpp index ea1bca7a..eb14fda8 100644 --- a/firmware/application/apps/ui_ss_viewer.cpp +++ b/firmware/application/apps/ui_ss_viewer.cpp @@ -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; } } diff --git a/firmware/application/apps/ui_ss_viewer.hpp b/firmware/application/apps/ui_ss_viewer.hpp index 2199a109..85251325 100644 --- a/firmware/application/apps/ui_ss_viewer.hpp +++ b/firmware/application/apps/ui_ss_viewer.hpp @@ -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" diff --git a/firmware/application/apps/ui_sstvtx.hpp b/firmware/application/apps/ui_sstvtx.hpp index fecd2478..72f9734f 100644 --- a/firmware/application/apps/ui_sstvtx.hpp +++ b/firmware/application/apps/ui_sstvtx.hpp @@ -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}, diff --git a/firmware/application/apps/ui_subghzd.hpp b/firmware/application/apps/ui_subghzd.hpp index d26ce67e..8594996e 100644 --- a/firmware/application/apps/ui_subghzd.hpp +++ b/firmware/application/apps/ui_subghzd.hpp @@ -156,9 +156,9 @@ 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{ diff --git a/firmware/application/apps/ui_test.hpp b/firmware/application/apps/ui_test.hpp index bb3861bf..c39f6077 100644 --- a/firmware/application/apps/ui_test.hpp +++ b/firmware/application/apps/ui_test.hpp @@ -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}, diff --git a/firmware/application/apps/ui_text_editor.cpp b/firmware/application/apps/ui_text_editor.cpp index fdf4a0de..cb57704b 100644 --- a/firmware/application/apps/ui_text_editor.cpp +++ b/firmware/application/apps/ui_text_editor.cpp @@ -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; diff --git a/firmware/application/apps/ui_text_editor.hpp b/firmware/application/apps/ui_text_editor.hpp index bb8b98b8..18fdeb65 100644 --- a/firmware/application/apps/ui_text_editor.hpp +++ b/firmware/application/apps/ui_text_editor.hpp @@ -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{ diff --git a/firmware/application/apps/ui_tone_search.hpp b/firmware/application/apps/ui_tone_search.hpp index a36dac73..88499ef5 100644 --- a/firmware/application/apps/ui_tone_search.hpp +++ b/firmware/application/apps/ui_tone_search.hpp @@ -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}}; diff --git a/firmware/application/apps/ui_touchtunes.hpp b/firmware/application/apps/ui_touchtunes.hpp index 49a3537f..5a0f7145 100644 --- a/firmware/application/apps/ui_touchtunes.hpp +++ b/firmware/application/apps/ui_touchtunes.hpp @@ -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 buttons{}; diff --git a/firmware/application/apps/ui_view_wav.cpp b/firmware/application/apps/ui_view_wav.cpp index 78ec1b8c..1272ca8e 100644 --- a/firmware/application/apps/ui_view_wav.cpp +++ b/firmware/application/apps/ui_view_wav.cpp @@ -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++) diff --git a/firmware/application/apps/ui_view_wav.hpp b/firmware/application/apps/ui_view_wav.hpp index 2d235d17..b460855a 100644 --- a/firmware/application/apps/ui_view_wav.hpp +++ b/firmware/application/apps/ui_view_wav.hpp @@ -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}}; diff --git a/firmware/application/apps/ui_weatherstation.hpp b/firmware/application/apps/ui_weatherstation.hpp index c31bf628..84b98d79 100644 --- a/firmware/application/apps/ui_weatherstation.hpp +++ b/firmware/application/apps/ui_weatherstation.hpp @@ -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{ diff --git a/firmware/application/apps/ui_whipcalc.hpp b/firmware/application/apps/ui_whipcalc.hpp index 2ef8fc90..0f807c5f 100644 --- a/firmware/application/apps/ui_whipcalc.hpp +++ b/firmware/application/apps/ui_whipcalc.hpp @@ -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}, diff --git a/firmware/application/debug.cpp b/firmware/application/debug.cpp index 4713b636..f15538b2 100644 --- a/firmware/application/debug.cpp +++ b/firmware/application/debug.cpp @@ -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; } diff --git a/firmware/application/external/analogtv/analog_tv_app.cpp b/firmware/application/external/analogtv/analog_tv_app.cpp index 795ea51b..8251d94c 100644 --- a/firmware/application/external/analogtv/analog_tv_app.cpp +++ b/firmware/application/external/analogtv/analog_tv_app.cpp @@ -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 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(options_view_rect, style_options_group_new.background); + options_widget = std::make_unique(options_view_rect, Theme::getInstance()->option_active->background); } add_child(options_widget.get()); } void AnalogTvView::on_show_options_frequency() { - auto widget = std::make_unique(options_view_rect, &style_options_group_new); + auto widget = std::make_unique(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(options_view_rect, &style_options_group_new); + auto widget = std::make_unique(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) { diff --git a/firmware/application/external/analogtv/analog_tv_app.hpp b/firmware/application/external/analogtv/analog_tv_app.hpp index 053e5442..c056c7d9 100644 --- a/firmware/application/external/analogtv/analog_tv_app.hpp +++ b/firmware/application/external/analogtv/analog_tv_app.hpp @@ -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" diff --git a/firmware/application/external/audio_test/ui_audio_test.hpp b/firmware/application/external/audio_test/ui_audio_test.hpp index 7e5f9c91..1d6119b5 100644 --- a/firmware/application/external/audio_test/ui_audio_test.hpp +++ b/firmware/application/external/audio_test/ui_audio_test.hpp @@ -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 */ diff --git a/firmware/application/external/coasterp/ui_coasterp.hpp b/firmware/application/external/coasterp/ui_coasterp.hpp index e989f987..5856f92c 100644 --- a/firmware/application/external/coasterp/ui_coasterp.hpp +++ b/firmware/application/external/coasterp/ui_coasterp.hpp @@ -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}, diff --git a/firmware/application/external/extsensors/ui_extsensors.hpp b/firmware/application/external/extsensors/ui_extsensors.hpp index e068ff6d..e0472361 100644 --- a/firmware/application/external/extsensors/ui_extsensors.hpp +++ b/firmware/application/external/extsensors/ui_extsensors.hpp @@ -55,9 +55,9 @@ class ExtSensorsView : public View { bool has_data = false; Labels labels{ - {{0 * 8, 3 * 16}, "GPS:", Color::light_grey()}, - {{0 * 8, 5 * 16}, "ORI:", Color::light_grey()}, - {{0 * 8, 7 * 16}, "ENV:", Color::light_grey()}}; + {{0 * 8, 3 * 16}, "GPS:", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 5 * 16}, "ORI:", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 7 * 16}, "ENV:", Theme::getInstance()->fg_light->foreground}}; Text text_info{{0 * 8, 0 * 8, 30 * 8, 16 * 1}, "Connect a compatible module..."}; Text text_gps{{5 * 8, 3 * 16, 24 * 8, 16}, "-"}; diff --git a/firmware/application/external/font_viewer/ui_font_viewer.cpp b/firmware/application/external/font_viewer/ui_font_viewer.cpp index 64be431e..b78fbcff 100644 --- a/firmware/application/external/font_viewer/ui_font_viewer.cpp +++ b/firmware/application/external/font_viewer/ui_font_viewer.cpp @@ -22,7 +22,6 @@ #include "ui_font_viewer.hpp" #include "ui_font_fixed_8x16.hpp" -#include "ui_styles.hpp" #include "ui_painter.hpp" #include "portapack.hpp" @@ -57,8 +56,8 @@ uint16_t DebugFontsView::display_font(Painter& painter, uint16_t y_offset, const void DebugFontsView::paint(Painter& painter) { int16_t line_pos; - line_pos = display_font(painter, 32, &Styles::white, "Fixed 8x16"); - display_font(painter, line_pos + 16, &Styles::white_small, "Fixed 5x8"); + line_pos = display_font(painter, 32, Theme::getInstance()->bg_darkest, "Fixed 8x16"); + display_font(painter, line_pos + 16, Theme::getInstance()->bg_darkest_small, "Fixed 5x8"); } DebugFontsView::DebugFontsView(NavigationView& nav) diff --git a/firmware/application/external/gpssim/gps_sim_app.hpp b/firmware/application/external/gpssim/gps_sim_app.hpp index 5efb3493..ba967177 100644 --- a/firmware/application/external/gpssim/gps_sim_app.hpp +++ b/firmware/application/external/gpssim/gps_sim_app.hpp @@ -114,8 +114,8 @@ class GpsSimAppView : 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{}; diff --git a/firmware/application/external/jammer/ui_jammer.cpp b/firmware/application/external/jammer/ui_jammer.cpp index 19fd689e..c8c43f81 100644 --- a/firmware/application/external/jammer/ui_jammer.cpp +++ b/firmware/application/external/jammer/ui_jammer.cpp @@ -99,20 +99,20 @@ void RangeView::paint(Painter&) { r = button_center.screen_rect(); p = r.center() + Point(0, r.height() / 2); - display.draw_line(p, p + Point(0, 10), Color::grey()); + display.draw_line(p, p + Point(0, 10), Theme::getInstance()->fg_medium->foreground); r = button_width.screen_rect(); c = r.top() + (r.height() / 2); p = {r.left() - 64, c}; - display.draw_line({r.left(), c}, p, Color::grey()); - display.draw_line(p, p + Point(10, -10), Color::grey()); - display.draw_line(p, p + Point(10, 10), Color::grey()); + display.draw_line({r.left(), c}, p, Theme::getInstance()->fg_medium->foreground); + display.draw_line(p, p + Point(10, -10), Theme::getInstance()->fg_medium->foreground); + display.draw_line(p, p + Point(10, 10), Theme::getInstance()->fg_medium->foreground); p = {r.right() + 64, c}; - display.draw_line({r.right(), c}, p, Color::grey()); - display.draw_line(p, p + Point(-10, -10), Color::grey()); - display.draw_line(p, p + Point(-10, 10), Color::grey()); + display.draw_line({r.right(), c}, p, Theme::getInstance()->fg_medium->foreground); + display.draw_line(p, p + Point(-10, -10), Theme::getInstance()->fg_medium->foreground); + display.draw_line(p, p + Point(-10, 10), Theme::getInstance()->fg_medium->foreground); } RangeView::RangeView(NavigationView& nav) { diff --git a/firmware/application/external/jammer/ui_jammer.hpp b/firmware/application/external/jammer/ui_jammer.hpp index d39d48b8..3a34dbf2 100644 --- a/firmware/application/external/jammer/ui_jammer.hpp +++ b/firmware/application/external/jammer/ui_jammer.hpp @@ -23,7 +23,6 @@ #include "ui.hpp" #include "ui_language.hpp" #include "ui_widget.hpp" -#include "ui_styles.hpp" #include "ui_navigation.hpp" #include "ui_tabview.hpp" #include "transmitter_model.hpp" @@ -54,13 +53,13 @@ class RangeView : public View { uint32_t width{}; rf::Frequency center{}; - const Style& style_info = Styles::grey; + const Style& style_info = *Theme::getInstance()->fg_medium; Labels labels{ - {{2 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_START], Color::light_grey()}, - {{23 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_STOP], Color::light_grey()}, - {{12 * 8, 5 * 8 - 4}, "Center", Color::light_grey()}, - {{12 * 8 + 4, 13 * 8}, "Width", Color::light_grey()}}; + {{2 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_START], Theme::getInstance()->fg_light->foreground}, + {{23 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_STOP], Theme::getInstance()->fg_light->foreground}, + {{12 * 8, 5 * 8 - 4}, "Center", Theme::getInstance()->fg_light->foreground}, + {{12 * 8 + 4, 13 * 8}, "Width", Theme::getInstance()->fg_light->foreground}}; Checkbox check_enabled{ {1 * 8, 4}, @@ -120,8 +119,8 @@ class JammerView : public View { int16_t mscounter = 0; // euquiq: Internal ms counter for do_timer() lfsr_word_t lfsr_v = 1; // euquiq: Used to generate "random" Jitter - const Style& style_val = Styles::green; - const Style& style_cancel = Styles::red; + const Style& style_val = *Theme::getInstance()->fg_green; + const Style& style_cancel = *Theme::getInstance()->fg_red; RangeView view_range_a{nav_}; RangeView view_range_b{nav_}; @@ -130,23 +129,23 @@ class JammerView : public View { std::array range_views{{&view_range_a, &view_range_b, &view_range_c}}; TabView tab_view{ - {"Range 1", Color::white(), range_views[0]}, - {"Range 2", Color::white(), range_views[1]}, - {"Range 3", Color::white(), range_views[2]}, + {"Range 1", Theme::getInstance()->bg_darkest->foreground, range_views[0]}, + {"Range 2", Theme::getInstance()->bg_darkest->foreground, range_views[1]}, + {"Range 3", Theme::getInstance()->bg_darkest->foreground, range_views[2]}, }; Labels labels{ - {{2 * 8, 23 * 8}, "Type:", Color::light_grey()}, - {{1 * 8, 25 * 8}, "Speed:", Color::light_grey()}, - {{3 * 8, 27 * 8}, "Hop:", Color::light_grey()}, - {{4 * 8, 29 * 8}, "TX:", Color::light_grey()}, - {{1 * 8, 31 * 8}, "Sle3p:", Color::light_grey()}, // euquiq: Token of appreciation to TheSle3p, which made this ehnancement a reality with his bounty. - {{0 * 8, 33 * 8}, "Jitter:", Color::light_grey()}, // Maybe the repository curator can keep the "mystype" for some versions. - {{11 * 8, 29 * 8}, "Secs.", Color::light_grey()}, - {{11 * 8, 31 * 8}, "Secs.", Color::light_grey()}, - {{11 * 8, 33 * 8}, "/60", Color::light_grey()}, - {{2 * 8, 35 * 8}, "Gain:", Color::light_grey()}, - {{11 * 8, 35 * 8}, "A:", Color::light_grey()}}; + {{2 * 8, 23 * 8}, "Type:", Theme::getInstance()->fg_light->foreground}, + {{1 * 8, 25 * 8}, "Speed:", Theme::getInstance()->fg_light->foreground}, + {{3 * 8, 27 * 8}, "Hop:", Theme::getInstance()->fg_light->foreground}, + {{4 * 8, 29 * 8}, "TX:", Theme::getInstance()->fg_light->foreground}, + {{1 * 8, 31 * 8}, "Sle3p:", Theme::getInstance()->fg_light->foreground}, // euquiq: Token of appreciation to TheSle3p, which made this ehnancement a reality with his bounty. + {{0 * 8, 33 * 8}, "Jitter:", Theme::getInstance()->fg_light->foreground}, // Maybe the repository curator can keep the "mystype" for some versions. + {{11 * 8, 29 * 8}, "Secs.", Theme::getInstance()->fg_light->foreground}, + {{11 * 8, 31 * 8}, "Secs.", Theme::getInstance()->fg_light->foreground}, + {{11 * 8, 33 * 8}, "/60", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 35 * 8}, "Gain:", Theme::getInstance()->fg_light->foreground}, + {{11 * 8, 35 * 8}, "A:", Theme::getInstance()->fg_light->foreground}}; OptionsField options_type{ {7 * 8, 23 * 8}, diff --git a/firmware/application/external/keyfob/ui_keyfob.hpp b/firmware/application/external/keyfob/ui_keyfob.hpp index 4e23780a..970598b5 100644 --- a/firmware/application/external/keyfob/ui_keyfob.hpp +++ b/firmware/application/external/keyfob/ui_keyfob.hpp @@ -76,11 +76,11 @@ class KeyfobView : public View { void subaru_set_command(const uint32_t command); Labels labels{ - {{5 * 8, 1 * 16}, "Make:", Color::light_grey()}, - {{2 * 8, 2 * 16}, "Command:", Color::light_grey()}, - {{2 * 8, 4 * 16}, "Payload: #####", Color::light_grey()}, - {{2 * 8, 7 * 16}, "Checksum is fixed just", Color::light_grey()}, - {{2 * 8, 8 * 16}, "before transmission.", Color::light_grey()}, + {{5 * 8, 1 * 16}, "Make:", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 2 * 16}, "Command:", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 4 * 16}, "Payload: #####", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 7 * 16}, "Checksum is fixed just", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 8 * 16}, "before transmission.", Theme::getInstance()->fg_light->foreground}, }; OptionsField options_make{ diff --git a/firmware/application/external/lcr/ui_lcr.cpp b/firmware/application/external/lcr/ui_lcr.cpp index c451c9ea..6181dbcf 100644 --- a/firmware/application/external/lcr/ui_lcr.cpp +++ b/firmware/application/external/lcr/ui_lcr.cpp @@ -237,7 +237,7 @@ LCRView::LCRView(NavigationView& nav) { rectangle->set_parent_rect({static_cast(98), static_cast(n * 32 + 66), 68, 20}); - rectangle->set_color(ui::Color::grey()); + rectangle->set_color(Theme::getInstance()->fg_medium->foreground); rectangle->set_outline(true); add_child(rectangle); diff --git a/firmware/application/external/lcr/ui_lcr.hpp b/firmware/application/external/lcr/ui_lcr.hpp index 390123b2..d0767fc8 100644 --- a/firmware/application/external/lcr/ui_lcr.hpp +++ b/firmware/application/external/lcr/ui_lcr.hpp @@ -105,8 +105,8 @@ class LCRView : public View { std::string generate_message(std::string rgsb, std::vector litterals, size_t option_ec); Labels labels{ - {{0, 8}, "EC: RGSB:", Color::light_grey()}, - {{17 * 8, 4 * 8}, "List:", Color::light_grey()}}; + {{0, 8}, "EC: RGSB:", Theme::getInstance()->fg_light->foreground}, + {{17 * 8, 4 * 8}, "List:", Theme::getInstance()->fg_light->foreground}}; std::array buttons{}; std::array checkboxes{}; diff --git a/firmware/application/external/lge/lge_app.hpp b/firmware/application/external/lge/lge_app.hpp index 3db41ba2..fdef3807 100644 --- a/firmware/application/external/lge/lge_app.hpp +++ b/firmware/application/external/lge/lge_app.hpp @@ -88,16 +88,16 @@ class LGEView : public View { void on_tx_progress(const uint32_t progress, const bool done); Labels labels{ - //{ { 7 * 8, 1 * 8 }, "NO FUN ALLOWED !", Color::red() }, - {{1 * 8, 1 * 8}, "Frame:", Color::light_grey()}, - {{2 * 8, 3 * 8}, "Room:", Color::light_grey()}, - {{14 * 8, 3 * 8}, "Text:", Color::light_grey()}, - {{2 * 8, 5 * 8}, "Team:", Color::light_grey()}, - {{0 * 8, 7 * 8}, "Player:", Color::light_grey()}, - {{0 * 8, 10 * 8}, "Vest:", Color::light_grey()}, - {{4 * 8, 12 * 8}, "ID:", Color::light_grey()}, - {{3 * 8, 14 * 8}, "Pow: /10", Color::light_grey()}, - {{2 * 8, 16 * 8}, "Time: x100ms", Color::light_grey()}}; + //{ { 7 * 8, 1 * 8 }, "NO FUN ALLOWED !", Theme::getInstance()->error_dark->foreground }, + {{1 * 8, 1 * 8}, "Frame:", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 3 * 8}, "Room:", Theme::getInstance()->fg_light->foreground}, + {{14 * 8, 3 * 8}, "Text:", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 5 * 8}, "Team:", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 7 * 8}, "Player:", Theme::getInstance()->fg_light->foreground}, + {{0 * 8, 10 * 8}, "Vest:", Theme::getInstance()->fg_light->foreground}, + {{4 * 8, 12 * 8}, "ID:", Theme::getInstance()->fg_light->foreground}, + {{3 * 8, 14 * 8}, "Pow: /10", Theme::getInstance()->fg_light->foreground}, + {{2 * 8, 16 * 8}, "Time: x100ms", Theme::getInstance()->fg_light->foreground}}; OptionsField options_frame{ {7 * 8, 1 * 8}, diff --git a/firmware/application/external/spainter/ui_spectrum_painter.cpp b/firmware/application/external/spainter/ui_spectrum_painter.cpp index ceeb1f81..31cb4ce6 100644 --- a/firmware/application/external/spainter/ui_spectrum_painter.cpp +++ b/firmware/application/external/spainter/ui_spectrum_painter.cpp @@ -190,8 +190,8 @@ void SpectrumPainterView::paint(Painter& painter) { painter.draw_bitmap( pos, bitmap_stripes, - ui::Color(191, 191, 0), - ui::Color::black()); + Theme::getInstance()->fg_yellow->foreground, + Theme::getInstance()->fg_yellow->background); if (c != 9) pos += {24, 0}; else diff --git a/firmware/application/external/spainter/ui_spectrum_painter.hpp b/firmware/application/external/spainter/ui_spectrum_painter.hpp index ba780a67..af9bd883 100644 --- a/firmware/application/external/spainter/ui_spectrum_painter.hpp +++ b/firmware/application/external/spainter/ui_spectrum_painter.hpp @@ -83,16 +83,16 @@ class SpectrumPainterView : public View { std::array input_views{{&input_image, &input_text}}; TabView tab_view{ - {"Image", Color::white(), input_views[0]}, - {"Text", Color::white(), input_views[1]}}; + {"Image", Theme::getInstance()->bg_darkest->foreground, input_views[0]}, + {"Text", Theme::getInstance()->bg_darkest->foreground, input_views[1]}}; static constexpr int32_t footer_location = 15 * 16 + 8; ProgressBar progressbar{ {4, footer_location - 16, 240 - 8, 16}}; Labels labels{ - {{10 * 8, footer_location + 1 * 16}, "GAIN A:", Color::light_grey()}, - {{1 * 8, footer_location + 2 * 16}, "BW: Du: P:", Color::light_grey()}, + {{10 * 8, footer_location + 1 * 16}, "GAIN A:", Theme::getInstance()->fg_light->foreground}, + {{1 * 8, footer_location + 2 * 16}, "BW: Du: P:", Theme::getInstance()->fg_light->foreground}, }; TxFrequencyField field_frequency{ @@ -122,8 +122,8 @@ class SpectrumPainterView : public View { ImageButton button_play{ {28 * 8, footer_location + 1 * 16, 2 * 8, 1 * 16}, &bitmap_play, - Color::green(), - Color::black()}; + Theme::getInstance()->fg_green->foreground, + Theme::getInstance()->fg_green->background}; OptionsField option_bandwidth{ {4 * 8, footer_location + 2 * 16}, diff --git a/firmware/application/external/tetris/SPI_TFT_ILI9341.h b/firmware/application/external/tetris/SPI_TFT_ILI9341.h index a6dde5b9..8f727f4e 100644 --- a/firmware/application/external/tetris/SPI_TFT_ILI9341.h +++ b/firmware/application/external/tetris/SPI_TFT_ILI9341.h @@ -96,7 +96,7 @@ static void rect(int x1, int y1, int x2, int y2, int color) { }; static void printf(std::string str) { - auto style = (fg_color == White) ? ui::Styles::white : ui::Styles::bg_white; + auto style = (fg_color == White) ? *ui::Theme::getInstance()->bg_darkest : *ui::Theme::getInstance()->bg_lightest; painter.draw_string({x_pos, y_pos - 1}, style, str); }; diff --git a/firmware/application/external/tetris/ui_tetris.hpp b/firmware/application/external/tetris/ui_tetris.hpp index 8fc71d69..44bb7788 100644 --- a/firmware/application/external/tetris/ui_tetris.hpp +++ b/firmware/application/external/tetris/ui_tetris.hpp @@ -26,7 +26,6 @@ #include "event_m0.hpp" #include "message.hpp" #include "irq_controls.hpp" -#include "ui_styles.hpp" #include "random.hpp" #include "lpc43xx_cpp.hpp" #include "limits.h" diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index cff6762f..b0f56fec 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -187,6 +187,8 @@ int main(void) { lcd_frame_sync_configure(); rtc_interrupt_enable(); + Theme::SetTheme((Theme::ThemeId)portapack::persistent_memory::ui_theme_id()); // load theme + event_loop(); sdcDisconnect(&SDCD1); diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 0a211dce..b3927f76 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -380,8 +380,8 @@ static void draw_splash_screen_icon(int16_t n, const ui::Bitmap& bitmap) { painter.draw_bitmap( {portapack::display.width() / 2 - 8 - 40 + (n * 20), portapack::display.height() / 2 - 8 + 40}, bitmap, - ui::Color::white(), - ui::Color::black()); + Theme::getInstance()->bg_darkest->foreground, + Theme::getInstance()->bg_darkest->background); } static bool is_portapack_present() { @@ -440,7 +440,7 @@ static void initialize_boot_splash_screen() { painter.fill_rectangle( {0, 0, portapack::display.width(), portapack::display.height()}, - ui::Color::black()); + Theme::getInstance()->bg_darkest->background); chThdSleepMilliseconds(17); portapack::backlight()->on(); @@ -448,8 +448,8 @@ static void initialize_boot_splash_screen() { painter.draw_bitmap( {portapack::display.width() / 2 - 40, portapack::display.height() / 2 - 8}, ui::bitmap_titlebar_image, - ui::Color::white(), - ui::Color::black()); + Theme::getInstance()->bg_darkest->foreground, + Theme::getInstance()->bg_darkest->background); } /* Clock scheme after exiting bootloader in SPIFI mode: diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp index fa3efc86..3457bd74 100644 --- a/firmware/application/portapack.hpp +++ b/firmware/application/portapack.hpp @@ -39,6 +39,7 @@ #include "clock_manager.hpp" #include "temperature_logger.hpp" #include "battery.hpp" +#include "theme.hpp" /* TODO: This would be better as a class to add * guardrails on setting properties. */ diff --git a/firmware/application/recent_entries.cpp b/firmware/application/recent_entries.cpp index 61a61e1e..2cbb7d9b 100644 --- a/firmware/application/recent_entries.cpp +++ b/firmware/application/recent_entries.cpp @@ -39,7 +39,7 @@ void RecentEntriesHeader::paint(Painter& painter) { const Style style{ .font = parent_style.font, - .background = Color::blue(), + .background = *Theme::getInstance()->bg_table_header, .foreground = parent_style.foreground, }; diff --git a/firmware/application/theme.cpp b/firmware/application/theme.cpp new file mode 100644 index 00000000..7d46df93 --- /dev/null +++ b/firmware/application/theme.cpp @@ -0,0 +1,456 @@ + +#include "theme.hpp" + +namespace ui { + +ThemeTemplate* Theme::current = nullptr; + +ThemeTemplate* Theme::getInstance() { + if (current == nullptr) SetTheme(DefaultGrey); + return Theme::current; +} + +void Theme::SetTheme(ThemeId theme) { + if (current != nullptr) delete current; + switch (theme) { + case Yellow: + current = new ThemeYellow(); + break; + case Aqua: + current = new ThemeAqua(); + break; + case DefaultGrey: + default: + current = new ThemeDefault(); + break; + } +} + +ThemeTemplate::~ThemeTemplate() { + delete bg_lightest; + delete bg_lightest_small; + delete bg_light; + delete bg_medium; + delete bg_dark; + delete bg_darker; + delete bg_darkest; + delete bg_darkest_small; + delete bg_important_small; + delete error_dark; + delete warning_dark; + delete ok_dark; + delete fg_dark; + delete fg_medium; + delete fg_light; + delete fg_red; + delete fg_green; + delete fg_yellow; + delete fg_orange; + delete fg_blue; + delete fg_cyan; + delete fg_darkcyan; + delete fg_magenta; + delete option_active; + delete status_active; // green, the status bar icons when active + delete bg_table_header; +} + +ThemeYellow::ThemeYellow() { + bg_lightest = new Style{ + .font = font::fixed_8x16, + .background = {255, 255, 204}, + .foreground = Color::black(), + }; + bg_lightest_small = new Style{ + .font = font::fixed_8x16, + .background = {255, 255, 204}, + .foreground = Color::black(), + }; + bg_light = new Style{ + .font = font::fixed_8x16, + .background = {255, 255, 102}, + .foreground = Color::white(), + }; + bg_medium = new Style{ + .font = font::fixed_8x16, + .background = {204, 204, 0}, + .foreground = Color::white(), + }; + bg_dark = new Style{ + .font = font::fixed_8x16, + .background = {153, 153, 0}, + .foreground = Color::white(), + }; + bg_darker = new Style{ + .font = font::fixed_8x16, + .background = {102, 102, 0}, + .foreground = Color::white(), + }; + + bg_darkest = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::white(), + }; + bg_darkest_small = new Style{ + .font = font::fixed_5x8, + .background = {31, 31, 0}, + .foreground = Color::white(), + }; + + bg_important_small = new Style{ + .font = ui::font::fixed_5x8, + .background = ui::Color::yellow(), + .foreground = {31, 31, 0}, + }; + + error_dark = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::red(), + }; + warning_dark = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::yellow(), + }; + ok_dark = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::green(), + }; + + fg_dark = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = {153, 153, 0}, + }; + fg_medium = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = {204, 204, 0}, + }; + fg_light = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::light_grey(), + }; + + fg_red = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::red(), + }; + fg_green = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::green(), + }; + fg_yellow = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::yellow(), + }; + fg_orange = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::orange(), + }; + fg_blue = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::blue(), + }; + fg_cyan = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::cyan(), + }; + fg_darkcyan = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::dark_cyan(), + }; + fg_magenta = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::magenta(), + }; + + option_active = new Style{ + .font = font::fixed_8x16, + .background = Color::orange(), + .foreground = Color::white(), + }; + + status_active = new Color{0, 255, 0}; // green, the status bar icons when active + + bg_table_header = new Color{205, 205, 0}; +} + +ThemeAqua::ThemeAqua() { + bg_lightest = new Style{ + .font = font::fixed_8x16, + .background = {204, 255, 255}, + .foreground = Color::black(), + }; + bg_lightest_small = new Style{ + .font = font::fixed_8x16, + .background = {204, 255, 255}, + .foreground = Color::black(), + }; + bg_light = new Style{ + .font = font::fixed_8x16, + .background = {102, 255, 255}, + .foreground = Color::white(), + }; + bg_medium = new Style{ + .font = font::fixed_8x16, + .background = {0, 144, 200}, + .foreground = Color::white(), + }; + bg_dark = new Style{ + .font = font::fixed_8x16, + .background = {0, 153, 153}, + .foreground = Color::white(), + }; + bg_darker = new Style{ + .font = font::fixed_8x16, + .background = {0, 102, 102}, + .foreground = Color::white(), + }; + + bg_darkest = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::white(), + }; + bg_darkest_small = new Style{ + .font = font::fixed_5x8, + .background = {0, 31, 31}, + .foreground = Color::white(), + }; + + bg_important_small = new Style{ + .font = ui::font::fixed_5x8, + .background = ui::Color::yellow(), + .foreground = {0, 31, 31}, + }; + + error_dark = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::red(), + }; + warning_dark = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::yellow(), + }; + ok_dark = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::green(), + }; + + fg_dark = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = {0, 153, 153}, + }; + fg_medium = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = {0, 204, 204}, + }; + fg_light = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::light_grey(), + }; + + fg_red = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::red(), + }; + fg_green = new Style{ + .font = font::fixed_8x16, + .background = {31, 31, 0}, + .foreground = Color::green(), + }; + fg_yellow = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::yellow(), + }; + fg_orange = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::orange(), + }; + fg_blue = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::blue(), + }; + fg_cyan = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::cyan(), + }; + fg_darkcyan = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::dark_cyan(), + }; + fg_magenta = new Style{ + .font = font::fixed_8x16, + .background = {0, 31, 31}, + .foreground = Color::magenta(), + }; + + option_active = new Style{ + .font = font::fixed_8x16, + .background = Color::blue(), + .foreground = Color::white(), + }; + + status_active = new Color{0, 255, 0}; // green, the status bar icons when active + + bg_table_header = new Color{0, 205, 205}; +} + +ThemeDefault::ThemeDefault() { + bg_lightest = new Style{ + .font = font::fixed_8x16, + .background = Color::white(), + .foreground = Color::black(), + }; + bg_lightest_small = new Style{ + .font = font::fixed_8x16, + .background = Color::white(), + .foreground = Color::black(), + }; + bg_light = new Style{ + .font = font::fixed_8x16, + .background = Color::light_grey(), + .foreground = Color::white(), + }; + bg_medium = new Style{ + .font = font::fixed_8x16, + .background = Color::grey(), + .foreground = Color::white(), + }; + bg_dark = new Style{ + .font = font::fixed_8x16, + .background = Color::dark_grey(), + .foreground = Color::white(), + }; + bg_darker = new Style{ + .font = font::fixed_8x16, + .background = Color::darker_grey(), + .foreground = Color::white(), + }; + + bg_darkest = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::white(), + }; + bg_darkest_small = new Style{ + .font = font::fixed_5x8, + .background = Color::black(), + .foreground = Color::white(), + }; + + bg_important_small = new Style{ + .font = ui::font::fixed_5x8, + .background = ui::Color::yellow(), + .foreground = ui::Color::black(), + }; + + error_dark = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::red(), + }; + warning_dark = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::yellow(), + }; + ok_dark = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::green(), + }; + + fg_dark = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::dark_grey(), + }; + fg_medium = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::grey(), + }; + fg_light = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::light_grey(), + }; + + fg_red = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::red(), + }; + fg_green = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::green(), + }; + fg_yellow = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::yellow(), + }; + fg_orange = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::orange(), + }; + fg_blue = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::blue(), + }; + fg_cyan = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::cyan(), + }; + fg_darkcyan = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::dark_cyan(), + }; + fg_magenta = new Style{ + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::magenta(), + }; + + option_active = new Style{ + .font = font::fixed_8x16, + .background = Color::blue(), + .foreground = Color::white(), + }; + + status_active = new Color{0, 255, 0}; // green, the status bar icons when active + bg_table_header = new Color{0, 0, 255}; +} + +} // namespace ui \ No newline at end of file diff --git a/firmware/application/theme.hpp b/firmware/application/theme.hpp new file mode 100644 index 00000000..ed5c72d7 --- /dev/null +++ b/firmware/application/theme.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2024 HTotoo + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __THEME_H__ +#define __THEME_H__ +#include +#include +#include +#include "ui_painter.hpp" +#include "ui_font_fixed_5x8.hpp" +#include "ui_font_fixed_8x16.hpp" + +namespace ui { + +class ThemeTemplate { + public: + ~ThemeTemplate(); + Style* bg_lightest; + Style* bg_lightest_small; + Style* bg_light; + Style* bg_medium; + Style* bg_dark; + Style* bg_darker; + + Style* bg_darkest; + Style* bg_darkest_small; + + Style* bg_important_small; + + Style* error_dark; + Style* warning_dark; + Style* ok_dark; + + Style* fg_dark; + Style* fg_medium; + Style* fg_light; + + Style* fg_red; + Style* fg_green; + Style* fg_yellow; + Style* fg_orange; + Style* fg_blue; + Style* fg_cyan; + Style* fg_darkcyan; + Style* fg_magenta; + + Style* option_active; + + Color* status_active; // green, the status bar icons when active + Color* bg_table_header; +}; + +class ThemeDefault : public ThemeTemplate { + public: + ThemeDefault(); +}; + +class ThemeYellow : public ThemeTemplate { + public: + ThemeYellow(); +}; + +class ThemeAqua : public ThemeTemplate { + public: + ThemeAqua(); +}; + +class Theme { + public: + enum ThemeId { + DefaultGrey = 0, + Yellow = 1, + Aqua = 2, + MAX + }; + static ThemeTemplate* getInstance(); + + static void SetTheme(ThemeId theme); + static ThemeTemplate* current; + + private: +}; + +} // namespace ui +#endif /*__THEME_H__*/ diff --git a/firmware/application/ui/ui_alphanum.cpp b/firmware/application/ui/ui_alphanum.cpp index acd30655..e58fe088 100644 --- a/firmware/application/ui/ui_alphanum.cpp +++ b/firmware/application/ui/ui_alphanum.cpp @@ -129,13 +129,13 @@ void AlphanumView::refresh_keys() { switch (shift_mode) { case ShiftMode::None: - button_shift.set_color(Color::dark_grey()); + button_shift.set_color(Theme::getInstance()->bg_dark->background); break; case ShiftMode::Shift: - button_shift.set_color(Color::black()); + button_shift.set_color(Theme::getInstance()->bg_darkest->background); break; case ShiftMode::ShiftLock: - button_shift.set_color(Color::dark_blue()); + button_shift.set_color(Theme::getInstance()->fg_blue->foreground); break; } } diff --git a/firmware/application/ui/ui_alphanum.hpp b/firmware/application/ui/ui_alphanum.hpp index 58af6d2e..3ae045fe 100644 --- a/firmware/application/ui/ui_alphanum.hpp +++ b/firmware/application/ui/ui_alphanum.hpp @@ -84,12 +84,12 @@ class AlphanumView : public TextEntryView { {192, 214, screen_width / 5, 38}, {}, &bitmap_icon_shift, - Color::dark_grey(), + Theme::getInstance()->bg_dark->background, /*vcenter*/ true}; Labels labels{ - {{1 * 8, 33 * 8}, "Raw:", Color::light_grey()}, - {{1 * 8, 35 * 8}, "AKA:", Color::light_grey()}}; + {{1 * 8, 33 * 8}, "Raw:", Theme::getInstance()->fg_light->foreground}, + {{1 * 8, 35 * 8}, "AKA:", Theme::getInstance()->fg_light->foreground}}; NumberField field_raw{ {5 * 8, 33 * 8}, diff --git a/firmware/application/ui/ui_bmpview.cpp b/firmware/application/ui/ui_bmpview.cpp index c3d50189..9a8a2380 100644 --- a/firmware/application/ui/ui_bmpview.cpp +++ b/firmware/application/ui/ui_bmpview.cpp @@ -106,7 +106,7 @@ void BMPViewer::get_line(ui::Color* line, uint32_t bx, uint32_t by, uint32_t cnt void BMPViewer::paint(Painter& painter) { if (!bmp.is_loaded()) { - painter.draw_string({48, 24}, ui::Styles::white, "Can't load BMP"); + painter.draw_string({48, 24}, *ui::Theme::getInstance()->bg_darkest, "Can't load BMP"); return; } // get where i can paint diff --git a/firmware/application/ui/ui_bmpview.hpp b/firmware/application/ui/ui_bmpview.hpp index ec4a349d..dbc40339 100644 --- a/firmware/application/ui/ui_bmpview.hpp +++ b/firmware/application/ui/ui_bmpview.hpp @@ -25,7 +25,6 @@ #include "ui.hpp" #include "ui_widget.hpp" #include "bmpfile.hpp" -#include "ui_styles.hpp" class BMPViewer : public Widget { public: diff --git a/firmware/application/ui/ui_btngrid.cpp b/firmware/application/ui/ui_btngrid.cpp index 1277fce1..8c6b60be 100644 --- a/firmware/application/ui/ui_btngrid.cpp +++ b/firmware/application/ui/ui_btngrid.cpp @@ -44,7 +44,7 @@ BtnGridView::BtnGridView( add_child(&arrow_more); arrow_more.set_focusable(false); - arrow_more.set_foreground(Color::black()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->background); } BtnGridView::~BtnGridView() { @@ -98,9 +98,9 @@ void BtnGridView::set_arrow_enabled(bool enabled) { void BtnGridView::on_tick_second() { if (more && blink) - arrow_more.set_foreground(Color::white()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->foreground); else - arrow_more.set_foreground(Color::black()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->background); blink = !blink; diff --git a/firmware/application/ui/ui_btngrid.hpp b/firmware/application/ui/ui_btngrid.hpp index 6cea1996..b20a3433 100644 --- a/firmware/application/ui/ui_btngrid.hpp +++ b/firmware/application/ui/ui_btngrid.hpp @@ -98,8 +98,8 @@ class BtnGridView : public View { Image arrow_more{ {228, 320 - 8, 8, 8}, &bitmap_more, - Color::white(), - Color::black()}; + Theme::getInstance()->bg_darkest->foreground, + Theme::getInstance()->bg_darkest->background}; int button_w = 240 / rows_; static constexpr int button_h = 48; diff --git a/firmware/application/ui/ui_channel.cpp b/firmware/application/ui/ui_channel.cpp index d6a2cfb4..cf308904 100644 --- a/firmware/application/ui/ui_channel.cpp +++ b/firmware/application/ui/ui_channel.cpp @@ -39,17 +39,17 @@ void Channel::paint(Painter& painter) { const Rect r0{r.left(), r.top(), x_max, r.height()}; painter.fill_rectangle( r0, - Color::blue()); + Theme::getInstance()->fg_blue->foreground); const Rect r1{r.left() + x_max, r.top(), 1, r.height()}; painter.fill_rectangle( r1, - Color::white()); + Theme::getInstance()->bg_darkest->foreground); const Rect r2{r.left() + x_max + 1, r.top(), r.width() - (x_max + 1), r.height()}; painter.fill_rectangle( r2, - Color::black()); + Theme::getInstance()->fg_blue->background); } void Channel::on_statistics_update(const ChannelStatistics& statistics) { diff --git a/firmware/application/ui/ui_freqlist.cpp b/firmware/application/ui/ui_freqlist.cpp index 76280be9..fcdc77e3 100644 --- a/firmware/application/ui/ui_freqlist.cpp +++ b/firmware/application/ui/ui_freqlist.cpp @@ -39,14 +39,14 @@ void FreqManUIList::paint(Painter& painter) { if (!db_ || db_->empty()) { auto line_position = rect.location() + Point{7 * 8, 6 * 16}; - painter.fill_rectangle(rect, Color::black()); - painter.draw_string(line_position, Styles::white, "Empty Category"); + painter.fill_rectangle(rect, Theme::getInstance()->bg_darkest->background); + painter.draw_string(line_position, *Theme::getInstance()->bg_darkest, "Empty Category"); return; } // Indicate when a file is too large by drawing in yellow. auto over_max = db_->entry_count() > freqman_default_max_entries; - auto base_style = over_max ? &Styles::yellow : &Styles::white; + auto base_style = over_max ? Theme::getInstance()->fg_yellow : Theme::getInstance()->bg_darkest; // TODO: could minimize redraw/re-read if necessary // with better change tracking. @@ -68,7 +68,7 @@ void FreqManUIList::paint(Painter& painter) { // Otherwise, if 'Raw' indicate an invalid entry by color. if (entry.type == freqman_type::Raw) - style = &Styles::light_grey; + style = Theme::getInstance()->fg_light; } // Pad right with ' ' so trailing chars are cleaned up. @@ -81,7 +81,7 @@ void FreqManUIList::paint(Painter& painter) { } // Draw a bounding rectangle when focused. - painter.draw_rectangle(rect, (has_focus() ? Color::white() : Color::black())); + painter.draw_rectangle(rect, (has_focus() ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background)); } void FreqManUIList::on_focus() { diff --git a/firmware/application/ui/ui_freqlist.hpp b/firmware/application/ui/ui_freqlist.hpp index f01a0c85..dab75190 100644 --- a/firmware/application/ui/ui_freqlist.hpp +++ b/firmware/application/ui/ui_freqlist.hpp @@ -26,7 +26,6 @@ #include "ui.hpp" #include "ui_painter.hpp" -#include "ui_styles.hpp" #include "ui_widget.hpp" #include "event_m0.hpp" #include "freqman.hpp" diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 3b48a95a..d2c895a6 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -32,7 +32,6 @@ using namespace portapack; #include "string_format.hpp" #include "complex.hpp" -#include "ui_styles.hpp" #include "ui_font_fixed_5x8.hpp" #include "file_path.hpp" @@ -138,8 +137,8 @@ void GeoPos::focus() { void GeoPos::hide_altandspeed() { // Color altitude grey to indicate it's not updated in manual panning mode - field_altitude.set_style(&Styles::grey); - field_speed.set_style(&Styles::grey); + field_altitude.set_style(Theme::getInstance()->fg_medium); + field_speed.set_style(Theme::getInstance()->fg_medium); } void GeoPos::set_altitude(int32_t altitude) { @@ -322,13 +321,13 @@ void GeoMap::draw_map_grid() { if (map_zoom <= MAP_ZOOM_RESOLUTION_LIMIT) return; - display.fill_rectangle({{0, r.top()}, {r.width(), r.height()}}, Color::black()); + display.fill_rectangle({{0, r.top()}, {r.width(), r.height()}}, Theme::getInstance()->bg_darkest->background); for (uint16_t line = y; line < r.height(); line += grid_spacing) { - display.fill_rectangle({{0, r.top() + line}, {r.width(), 1}}, Color::darker_grey()); + display.fill_rectangle({{0, r.top() + line}, {r.width(), 1}}, Theme::getInstance()->bg_darker->background); } for (uint16_t column = x; column < r.width(); column += grid_spacing) { - display.fill_rectangle({{column, r.top()}, {1, r.height()}}, Color::darker_grey()); + display.fill_rectangle({{column, r.top()}, {1, r.height()}}, Theme::getInstance()->bg_darker->background); } } diff --git a/firmware/application/ui/ui_geomap.hpp b/firmware/application/ui/ui_geomap.hpp index 3fc6f2b5..8133d115 100644 --- a/firmware/application/ui/ui_geomap.hpp +++ b/firmware/application/ui/ui_geomap.hpp @@ -110,12 +110,12 @@ class GeoPos : public View { spd_unit speed_unit_{}; Labels labels_position{ - {{1 * 8, 0 * 16}, "Alt:", Color::light_grey()}, - {{1 * 8, 1 * 16}, "Lat: \xB0 ' \"", Color::light_grey()}, // 0xB0 is degree ° symbol in our 8x16 font - {{1 * 8, 2 * 16}, "Lon: \xB0 ' \"", Color::light_grey()}, + {{1 * 8, 0 * 16}, "Alt:", Theme::getInstance()->fg_light->foreground}, + {{1 * 8, 1 * 16}, "Lat: \xB0 ' \"", Theme::getInstance()->fg_light->foreground}, // 0xB0 is degree ° symbol in our 8x16 font + {{1 * 8, 2 * 16}, "Lon: \xB0 ' \"", Theme::getInstance()->fg_light->foreground}, }; Labels label_spd_position{ - {{15 * 8, 0 * 16}, "Spd:", Color::light_grey()}, + {{15 * 8, 0 * 16}, "Spd:", Theme::getInstance()->fg_light->foreground}, }; NumberField field_altitude{ {6 * 8, 0 * 16}, diff --git a/firmware/application/ui/ui_menu.cpp b/firmware/application/ui/ui_menu.cpp index e34df795..06685a14 100644 --- a/firmware/application/ui/ui_menu.cpp +++ b/firmware/application/ui/ui_menu.cpp @@ -98,7 +98,7 @@ MenuView::MenuView( add_child(&arrow_more); arrow_more.set_focusable(false); - arrow_more.set_foreground(Color::black()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->background); } MenuView::~MenuView() { @@ -135,9 +135,9 @@ void MenuView::set_parent_rect(const Rect new_parent_rect) { void MenuView::on_tick_second() { if (more && blink) - arrow_more.set_foreground(Color::white()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->foreground); else - arrow_more.set_foreground(Color::black()); + arrow_more.set_foreground(Theme::getInstance()->bg_darkest->background); blink = !blink; diff --git a/firmware/application/ui/ui_menu.hpp b/firmware/application/ui/ui_menu.hpp index f0850903..dd83c3b6 100644 --- a/firmware/application/ui/ui_menu.hpp +++ b/firmware/application/ui/ui_menu.hpp @@ -113,8 +113,8 @@ class MenuView : public View { Image arrow_more{ {228, screen_height - 8, 8, 8}, &bitmap_more, - Color::white(), - Color::black()}; + Theme::getInstance()->bg_darkest->foreground, + Theme::getInstance()->bg_darkest->background}; const size_t item_height = 24; bool blink = false; diff --git a/firmware/application/ui/ui_receiver.cpp b/firmware/application/ui/ui_receiver.cpp index 283e849f..daffb293 100644 --- a/firmware/application/ui/ui_receiver.cpp +++ b/firmware/application/ui/ui_receiver.cpp @@ -113,7 +113,7 @@ void FrequencyField::paint(Painter& painter) { if (digit_mode_) { auto p = screen_pos(); p += {digit_ * char_width, 0}; - painter.draw_char(p, Styles::bg_blue, str_value[digit_]); + painter.draw_char(p, *Theme::getInstance()->option_active, str_value[digit_]); } } diff --git a/firmware/application/ui/ui_rssi.cpp b/firmware/application/ui/ui_rssi.cpp index 41e0a783..4d02aab7 100644 --- a/firmware/application/ui/ui_rssi.cpp +++ b/firmware/application/ui/ui_rssi.cpp @@ -69,13 +69,13 @@ void RSSI::paint(Painter& painter) { const Rect r0{r.left(), r.top(), x_min, r.height()}; painter.fill_rectangle( r0, - Color::blue()); + Theme::getInstance()->fg_blue->foreground); // x_avg const Rect r1{r.left() + x_min, r.top(), x_avg - x_min, r.height()}; painter.fill_rectangle( r1, - Color::red()); + Theme::getInstance()->fg_red->foreground); // x_avg middle marker const Rect r2{r.left() + x_avg, r.top(), 1, r.height()}; @@ -87,20 +87,20 @@ void RSSI::paint(Painter& painter) { const Rect r3{r.left() + x_avg + 1, r.top(), x_max - (x_avg + 1), r.height()}; painter.fill_rectangle( r3, - Color::red()); + Theme::getInstance()->fg_red->foreground); // filling last part in black const Rect r4{r.left() + x_max, r.top(), r.width() - x_max, r.height()}; painter.fill_rectangle( r4, - Color::black()); + Theme::getInstance()->bg_darkest->background); // show green peak value if (peak_enabled) { const Rect r5{r.left() + peak - 3, r.top(), 3, r.height()}; painter.fill_rectangle( r5, - Color::green()); + Theme::getInstance()->fg_green->foreground); } } else { // vertical bottom to top level meters diff --git a/firmware/application/ui/ui_spectrum.cpp b/firmware/application/ui/ui_spectrum.cpp index 1ee2f734..8e7e98ca 100644 --- a/firmware/application/ui/ui_spectrum.cpp +++ b/firmware/application/ui/ui_spectrum.cpp @@ -56,7 +56,7 @@ AudioSpectrumView::AudioSpectrumView( void AudioSpectrumView::paint(Painter& painter) { const auto r = screen_rect(); - painter.fill_rectangle(r, Color::black()); + painter.fill_rectangle(r, Theme::getInstance()->bg_darkest->background); // if( !spectrum_sampling_rate ) return; @@ -131,14 +131,14 @@ void FrequencyScale::clear() { } void FrequencyScale::clear_background(Painter& painter, const Rect r) { - painter.fill_rectangle(r, Color::black()); + painter.fill_rectangle(r, Theme::getInstance()->bg_darkest->background); } void FrequencyScale::draw_frequency_ticks(Painter& painter, const Rect r) { const auto x_center = r.width() / 2; const Rect tick{r.left() + x_center, r.top(), 1, r.height()}; - painter.fill_rectangle(tick, Color::white()); + painter.fill_rectangle(tick, Theme::getInstance()->bg_darkest->foreground); constexpr int tick_count_max = 4; float rough_tick_interval = float(spectrum_sampling_rate) / tick_count_max; @@ -166,12 +166,12 @@ void FrequencyScale::draw_frequency_ticks(Painter& painter, const Rect r) { const Coord offset_low = r.left() + x_center - pixel_offset; const Rect tick_low{offset_low, r.top(), 1, r.height()}; - painter.fill_rectangle(tick_low, Color::white()); + painter.fill_rectangle(tick_low, Theme::getInstance()->bg_darkest->foreground); painter.draw_string({offset_low + 2, r.top()}, style(), label); const Coord offset_high = r.left() + x_center + pixel_offset; const Rect tick_high{offset_high, r.top(), 1, r.height()}; - painter.fill_rectangle(tick_high, Color::white()); + painter.fill_rectangle(tick_high, Theme::getInstance()->bg_darkest->foreground); painter.draw_string({offset_high - 2 - label_width, r.top()}, style(), label); tick_offset += tick_interval; diff --git a/firmware/application/ui/ui_spectrum.hpp b/firmware/application/ui/ui_spectrum.hpp index defe618e..86b2a815 100644 --- a/firmware/application/ui/ui_spectrum.hpp +++ b/firmware/application/ui/ui_spectrum.hpp @@ -49,7 +49,7 @@ class AudioSpectrumView : public View { int16_t audio_spectrum[128]{0}; Labels labels{ - {{6 * 8, 0 * 16}, "Hz", Color::light_grey()}}; + {{6 * 8, 0 * 16}, "Hz", Theme::getInstance()->fg_light->foreground}}; NumberField field_frequency{ {0 * 8, 0 * 16}, @@ -64,7 +64,7 @@ class AudioSpectrumView : public View { 128, 0, false, - Color::white()}; + Theme::getInstance()->bg_darkest->foreground}; }; class FrequencyScale : public Widget { diff --git a/firmware/application/ui/ui_styles.cpp b/firmware/application/ui/ui_styles.cpp deleted file mode 100644 index e20f1f3f..00000000 --- a/firmware/application/ui/ui_styles.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2023 Kyle Reed - * - * 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_styles.hpp" -#include "ui_painter.hpp" -#include "ui_font_fixed_5x8.hpp" -#include "ui_font_fixed_8x16.hpp" - -using namespace ui; - -const Style Styles::white{ - .font = ui::font::fixed_8x16, - .background = ui::Color::black(), - .foreground = ui::Color::white(), -}; - -const Style Styles::bg_white{ - .font = ui::font::fixed_8x16, - .background = ui::Color::white(), - .foreground = ui::Color::black(), -}; - -const Style Styles::white_small{ - .font = font::fixed_5x8, - .background = Color::black(), - .foreground = Color::white(), -}; - -const Style Styles::bg_white_small{ - .font = ui::font::fixed_5x8, - .background = ui::Color::white(), - .foreground = ui::Color::black(), -}; - -const Style Styles::bg_yellow_small{ - .font = ui::font::fixed_5x8, - .background = ui::Color::yellow(), - .foreground = ui::Color::black(), -}; - -const Style Styles::yellow{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::yellow(), -}; - -const Style Styles::green{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::green(), -}; - -const Style Styles::red{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::red(), -}; - -const Style Styles::blue{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::blue(), -}; - -const Style Styles::bg_blue{ - .font = font::fixed_8x16, - .background = Color::blue(), - .foreground = Color::white(), -}; - -const Style Styles::bg_dark_blue{ - .font = font::fixed_8x16, - .background = Color::dark_blue(), - .foreground = Color::white(), -}; - -const Style Styles::light_grey{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::light_grey(), -}; - -const Style Styles::grey{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::grey(), -}; - -const Style Styles::dark_grey{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::dark_grey(), -}; - -const Style Styles::bg_dark_grey{ - .font = font::fixed_8x16, - .background = Color::dark_grey(), - .foreground = Color::white(), -}; - -const Style Styles::orange{ - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::orange(), -}; diff --git a/firmware/application/ui/ui_styles.hpp b/firmware/application/ui/ui_styles.hpp deleted file mode 100644 index a04090dd..00000000 --- a/firmware/application/ui/ui_styles.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2023 Kyle Reed - * - * This file is part of PortaPack. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __UI_STYLES_H__ -#define __UI_STYLES_H__ - -#include "ui_painter.hpp" - -namespace ui { - -class Styles { - public: - /* White foreground. */ - static const Style white; - - /* White background. */ - static const Style bg_white; - - /* White foreground, small font. */ - static const Style white_small; - - /* White background, small font. */ - static const Style bg_white_small; - - /* Red background, small font. */ - static const Style bg_yellow_small; - - /* Yellow foreground. */ - static const Style yellow; - - /* Green foreground. */ - static const Style green; - - /* Red foreground. */ - static const Style red; - - /* Blue foreground. */ - static const Style blue; - - /* Blue background. */ - static const Style bg_blue; - - /* Dark blue background. */ - static const Style bg_dark_blue; - - /* Light grey foreground. */ - static const Style light_grey; - - /* Grey foreground. */ - static const Style grey; - - /* Dark grey foreground. */ - static const Style dark_grey; - - /* Dark grey background. */ - static const Style bg_dark_grey; - - /* Orange foreground. */ - static const Style orange; -}; - -} // namespace ui - -#endif /*__UI_STYLES_H__*/ diff --git a/firmware/application/ui/ui_tabview.cpp b/firmware/application/ui/ui_tabview.cpp index 8b0dabd6..d23dd343 100644 --- a/firmware/application/ui/ui_tabview.cpp +++ b/firmware/application/ui/ui_tabview.cpp @@ -47,18 +47,18 @@ void Tab::set( void Tab::paint(Painter& painter) { const auto rect = screen_rect(); - const Color color = highlighted() ? Color::black() : Color::grey(); + const Color color = highlighted() ? Theme::getInstance()->bg_darkest->background : Theme::getInstance()->bg_medium->background; painter.fill_rectangle({rect.left(), rect.top(), rect.width() - 8, rect.height()}, color); if (!highlighted()) - painter.draw_hline({rect.left(), rect.top()}, rect.width() - 9, Color::light_grey()); + painter.draw_hline({rect.left(), rect.top()}, rect.width() - 9, Theme::getInstance()->fg_light->foreground); painter.draw_bitmap( {rect.right() - 8, rect.top()}, bitmap_tab_edge, color, - Color::dark_grey()); + Theme::getInstance()->bg_dark->background); auto text_point = rect.center() - Point(4, 0) - Point(text_.size() * 8 / 2, 16 / 2); @@ -68,7 +68,7 @@ void Tab::paint(Painter& painter) { text_); if (has_focus()) - painter.draw_hline(text_point + Point(0, 16), text_.size() * 8, Color::white()); + painter.draw_hline(text_point + Point(0, 16), text_.size() * 8, Theme::getInstance()->bg_darkest->foreground); } bool Tab::on_key(const KeyEvent key) { diff --git a/firmware/application/ui/ui_transmitter.cpp b/firmware/application/ui/ui_transmitter.cpp index 7b324f29..6ec24e7f 100644 --- a/firmware/application/ui/ui_transmitter.cpp +++ b/firmware/application/ui/ui_transmitter.cpp @@ -40,13 +40,13 @@ namespace ui { /* Gets a style indicating total TX gain level. */ static const Style* get_style_for_gain(uint8_t tot_gain) { - if (tot_gain > POWER_THRESHOLD_HIGH) return &Styles::red; + if (tot_gain > POWER_THRESHOLD_HIGH) return Theme::getInstance()->fg_red; if (tot_gain > POWER_THRESHOLD_MED) - return &Styles::orange; + return Theme::getInstance()->fg_orange; if (tot_gain > POWER_THRESHOLD_LOW) - return &Styles::yellow; + return Theme::getInstance()->fg_yellow; return nullptr; // Uses default. } @@ -61,8 +61,8 @@ void TransmitterView::paint(Painter& painter) { painter.draw_bitmap( pos, bitmap_stripes, - ui::Color(191, 191, 0), - ui::Color::black()); + Theme::getInstance()->fg_yellow->foreground, + Theme::getInstance()->fg_yellow->background); if (c != 9) pos += {24, 0}; else diff --git a/firmware/application/ui/ui_transmitter.hpp b/firmware/application/ui/ui_transmitter.hpp index d93108ae..d9b922cf 100644 --- a/firmware/application/ui/ui_transmitter.hpp +++ b/firmware/application/ui/ui_transmitter.hpp @@ -27,7 +27,6 @@ #include "ui_navigation.hpp" #include "ui_painter.hpp" #include "ui_receiver.hpp" -#include "ui_styles.hpp" #include "ui_widget.hpp" #include "rf_path.hpp" @@ -69,9 +68,9 @@ class TransmitterView : public View { void set_transmitting(const bool transmitting); private: - const Style& style_start = Styles::green; - const Style& style_stop = Styles::red; - const Style& style_locked = Styles::dark_grey; + const Style& style_start = *Theme::getInstance()->fg_green; + const Style& style_stop = *Theme::getInstance()->fg_red; + const Style& style_locked = *Theme::getInstance()->fg_dark; bool lock_{false}; bool transmitting_{false}; diff --git a/firmware/application/ui/ui_tv.hpp b/firmware/application/ui/ui_tv.hpp index 2fb9bf60..dd055027 100644 --- a/firmware/application/ui/ui_tv.hpp +++ b/firmware/application/ui/ui_tv.hpp @@ -50,7 +50,7 @@ class TimeScopeView : public View { int16_t audio_spectrum[128]{0}; /*Labels labels { - { { 6 * 8, 0 * 16 }, "Hz", Color::light_grey() } + { { 6 * 8, 0 * 16 }, "Hz", Theme::getInstance()->fg_light->foreground } };*/ /* NumberField field_frequency { @@ -67,7 +67,7 @@ class TimeScopeView : public View { 128, 0, false, - Color::white()}; + Theme::getInstance()->bg_darkest->foreground}; }; class TVView : public Widget { diff --git a/firmware/application/ui_external_items_menu_loader.cpp b/firmware/application/ui_external_items_menu_loader.cpp index f3c2cf10..b107bc1c 100644 --- a/firmware/application/ui_external_items_menu_loader.cpp +++ b/firmware/application/ui_external_items_menu_loader.cpp @@ -125,7 +125,7 @@ namespace ui { } }; } else { - gridItem.color = Color::light_grey(); + gridItem.color = Theme::getInstance()->fg_light->foreground; gridItem.bitmap = &bitmap_sd_card_error; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 813b3b2a..52ad58c1 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -75,7 +75,6 @@ // #include "ui_spectrum_painter.hpp" //moved to ext app #include "ui_ss_viewer.hpp" #include "ui_sstvtx.hpp" -#include "ui_styles.hpp" // #include "ui_test.hpp" #include "ui_text_editor.hpp" #include "ui_tone_search.hpp" @@ -293,7 +292,7 @@ SystemStatusView::SystemStatusView( pmem::set_config_sdcard_high_speed_io(pmem::config_sdcard_high_speed_io(), false); button_back.id = -1; // Special ID used by FocusManager - title.set_style(&Styles::bg_dark_grey); + title.set_style(Theme::getInstance()->bg_dark); button_back.on_select = [this](ImageButton&) { if (pmem::should_use_sdcard_for_pmem()) { @@ -429,23 +428,23 @@ void SystemStatusView::refresh() { // Clock status bool external_clk = portapack::clock_manager.get_reference().source == ClockManager::ReferenceSource::External; button_clock_status.set_bitmap(external_clk ? &bitmap_icon_clk_ext : &bitmap_icon_clk_int); - button_clock_status.set_foreground(pmem::clkout_enabled() ? Color::green() : Color::light_grey()); + button_clock_status.set_foreground(pmem::clkout_enabled() ? *Theme::getInstance()->status_active : Theme::getInstance()->fg_light->foreground); // Antenna DC Bias if (portapack::get_antenna_bias()) { button_bias_tee.set_bitmap(&bitmap_icon_biast_on); - button_bias_tee.set_foreground(Color::yellow()); + button_bias_tee.set_foreground(Theme::getInstance()->warning_dark->foreground); } else { button_bias_tee.set_bitmap(&bitmap_icon_biast_off); - button_bias_tee.set_foreground(Color::light_grey()); + button_bias_tee.set_foreground(Theme::getInstance()->fg_light->foreground); } // Converter button_converter.set_bitmap(pmem::config_updown_converter() ? &bitmap_icon_downconvert : &bitmap_icon_upconvert); - button_converter.set_foreground(pmem::config_converter() ? Color::red() : Color::light_grey()); + button_converter.set_foreground(pmem::config_converter() ? Theme::getInstance()->fg_red->foreground : Theme::getInstance()->fg_light->foreground); // Fake Brightness - button_fake_brightness.set_foreground(pmem::apply_fake_brightness() ? Color::green() : Color::light_grey()); + button_fake_brightness.set_foreground(pmem::apply_fake_brightness() ? *Theme::getInstance()->status_active : Theme::getInstance()->fg_light->foreground); set_dirty(); } @@ -604,28 +603,22 @@ void SystemStatusView::rtc_battery_workaround() { InformationView::InformationView( NavigationView& nav) : nav_(nav) { - static constexpr Style style_infobar{ - .font = font::fixed_8x16, - .background = {33, 33, 33}, - .foreground = Color::white(), - }; - add_children({&backdrop, &version, <ime}); #if GCC_VERSION_MISMATCH - version.set_style(&Styles::yellow); + version.set_style(Theme::getInstance()->warning_dark); #else - version.set_style(&style_infobar); + version.set_style(Theme::getInstance()->bg_darker); #endif if (firmware_checksum_error()) { version.set("FLASH ERR"); - version.set_style(&Styles::red); + version.set_style(Theme::getInstance()->error_dark); } - ltime.set_style(&style_infobar); + ltime.set_style(Theme::getInstance()->bg_darker); refresh(); set_dirty(); } @@ -786,7 +779,7 @@ void addExternalItems(NavigationView& nav, app_location_t location, BtnGridView& auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav); if (externalItems.empty()) { grid.insert_item({"Notice!", - Color::red(), + Theme::getInstance()->error_dark->foreground, nullptr, [&nav]() { nav.display_modal( @@ -811,7 +804,7 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) void ReceiversMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_item({"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}); + add_item({"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}); } add_apps(nav_, *this, RX); @@ -826,7 +819,7 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) void TransmittersMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); + add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}}); } add_apps(nav_, *this, TX); @@ -843,7 +836,7 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) void UtilitiesMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); + add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}}); } add_apps(nav_, *this, UTILITIES); @@ -874,7 +867,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav) void SystemMenuView::on_populate() { add_apps(nav_, *this, HOME); - add_item({"HackRF", Color::cyan(), &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }}); + add_item({"HackRF", Theme::getInstance()->fg_cyan->foreground, &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }}); } /* SystemView ************************************************************/ @@ -884,7 +877,7 @@ SystemView::SystemView( const Rect parent_rect) : View{parent_rect}, context_(context) { - set_style(&Styles::white); + set_style(Theme::getInstance()->bg_darkest); constexpr Dim status_view_height = 16; constexpr Dim info_view_height = 16; diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index ccc99088..ae28125e 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -30,6 +30,8 @@ #include #include "ui.hpp" +#include "theme.hpp" + #include "ui_widget.hpp" #include "ui_focus.hpp" #include "ui_menu.hpp" @@ -197,13 +199,13 @@ class SystemStatusView : public View { Rectangle backdrop{ {0 * 8, 0 * 16, ui::screen_width, 16}, - Color::dark_grey()}; + Theme::getInstance()->bg_dark->background}; ImageButton button_back{ {0, 0 * 16, 12 * 8, 16}, // Back button also covers the title for easier touch. &bitmap_icon_previous, - Color::white(), - Color::dark_grey()}; + Theme::getInstance()->bg_dark->foreground, + Theme::getInstance()->bg_dark->background}; Text title{ {20, 0, 14 * 8, 1 * 16}, @@ -213,8 +215,8 @@ class SystemStatusView : public View { ImageButton button_title{ {2, 0, 80, 16}, &bitmap_titlebar_image, - Color::white(), - Color::dark_grey()}; + Theme::getInstance()->bg_dark->foreground, + Theme::getInstance()->bg_dark->background}; StatusTray status_icons{{screen_width, 0}}; @@ -222,59 +224,64 @@ class SystemStatusView : public View { {0, 0, 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()->status_active, + Theme::getInstance()->bg_dark->background}; ImageToggle toggle_mute{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_speaker_and_headphones_mute, &bitmap_icon_speaker_and_headphones, - Color::light_grey(), - Color::dark_grey(), - Color::green(), - Color::dark_grey()}; + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background, + *Theme::getInstance()->status_active, + Theme::getInstance()->bg_dark->background}; ImageButton button_converter{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_upconvert, - Color::light_grey(), - Color::dark_grey()}; + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background}; ImageToggle toggle_stealth{ {0, 0, 2 * 8, 1 * 16}, - &bitmap_icon_stealth}; + &bitmap_icon_stealth, + &bitmap_icon_stealth, + *Theme::getInstance()->status_active, + Theme::getInstance()->bg_dark->background, + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background}; ImageButton button_camera{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_camera, - Color::white(), - Color::dark_grey()}; + Theme::getInstance()->bg_dark->foreground, + Theme::getInstance()->bg_dark->background}; ImageButton button_sleep{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_sleep, - Color::white(), - Color::dark_grey()}; + Theme::getInstance()->bg_dark->foreground, + Theme::getInstance()->bg_dark->background}; ImageButton button_bias_tee{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_biast_off, - Color::light_grey(), - Color::dark_grey()}; + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background}; ImageButton button_clock_status{ {0, 0 * 16, 8, 1 * 16}, &bitmap_icon_clk_int, - Color::light_grey(), - Color::dark_grey()}; + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background}; ImageButton button_fake_brightness{ {0, 0, 2 * 8, 1 * 16}, &bitmap_icon_brightness, - Color::green(), - Color::dark_grey()}; + *Theme::getInstance()->status_active, + Theme::getInstance()->bg_dark->background}; SDCardStatusView sd_card_status_view{ {0, 0 * 16, 2 * 8, 1 * 16}}; diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index f83a9411..64f7a6bf 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -51,9 +51,9 @@ namespace ui { shared_memory.application_queue.push(message); if( !pitch_rssi_enabled ) { - button_pitch_rssi.set_foreground(Color::orange()); + button_pitch_rssi.set_foreground(Theme::getInstance()->fg_orange->foreground); } else { - button_pitch_rssi.set_foreground(Color::green()); + button_pitch_rssi.set_foreground(Theme::getInstance()->fg_green->foreground); } }*/ @@ -113,9 +113,9 @@ uint32_t RecordView::set_sampling_rate(uint32_t new_sampling_rate) { // Change the "REC" icon background to yellow when the selected rate exceeds hardware limits. // Above this threshold, samples will be dropped resulting incomplete capture files. if (new_sampling_rate > 1'250'000) { - button_record.set_background(ui::Color::yellow()); + button_record.set_background(Theme::getInstance()->fg_yellow->foreground); } else { - button_record.set_background(ui::Color::black()); + button_record.set_background(Theme::getInstance()->fg_yellow->background); } if (sampling_rate != new_sampling_rate) { diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 68c57d57..dae35af9 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -113,21 +113,21 @@ class RecordView : public View { TrimProgressUI trim_ui{}; Rectangle rect_background{ - Color::black()}; + Theme::getInstance()->bg_darkest->background}; /*ImageButton button_pitch_rssi { { 2, 0 * 16, 3 * 8, 1 * 16 }, &bitmap_rssipwm, - Color::orange(), - Color::black() + Theme::getInstance()->fg_orange->foreground, + Theme::getInstance()->fg_orange->background };*/ ImageButton button_record{ //{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 }, {0 * 8, 0 * 16, 2 * 8, 1 * 16}, &bitmap_record, - Color::red(), - Color::black()}; + Theme::getInstance()->fg_red->foreground, + Theme::getInstance()->fg_red->background}; Text text_record_filename{ {7 * 8, 0 * 16, 8 * 8, 16}, @@ -147,8 +147,8 @@ class RecordView : public View { Image gps_icon{ {2 * 8 + 1, 0 * 16, 2 * 8, 1 * 16}, &bitmap_target, - Color::white(), - Color::black()}; + Theme::getInstance()->bg_darkest->foreground, + Theme::getInstance()->bg_darkest->background}; std::unique_ptr capture_thread{}; diff --git a/firmware/application/ui_sd_card_status_view.cpp b/firmware/application/ui_sd_card_status_view.cpp index 5efe8dae..7736aaff 100644 --- a/firmware/application/ui_sd_card_status_view.cpp +++ b/firmware/application/ui_sd_card_status_view.cpp @@ -54,9 +54,9 @@ const Bitmap& bitmap_sd_card(const sd_card::Status status) { } } -static constexpr Color color_sd_card_error = Color::red(); -static constexpr Color color_sd_card_unknown = Color::yellow(); -static constexpr Color color_sd_card_ok = Color::green(); +static Color color_sd_card_error = Theme::getInstance()->error_dark->foreground; +static Color color_sd_card_unknown = Theme::getInstance()->warning_dark->foreground; +static Color color_sd_card_ok = Theme::getInstance()->ok_dark->foreground; const Color color_sd_card(const sd_card::Status status) { switch (status) { @@ -83,7 +83,7 @@ const Color color_sd_card(const sd_card::Status status) { SDCardStatusView::SDCardStatusView( const Rect parent_rect) - : Image{parent_rect, &bitmap_sd_card_unknown, detail::color_sd_card_unknown, Color::dark_grey()} { + : Image{parent_rect, &bitmap_sd_card_unknown, detail::color_sd_card_unknown, Theme::getInstance()->bg_dark->background} { } void SDCardStatusView::on_show() { diff --git a/firmware/application/ui_sd_card_status_view.hpp b/firmware/application/ui_sd_card_status_view.hpp index a24c6535..e6f7bd03 100644 --- a/firmware/application/ui_sd_card_status_view.hpp +++ b/firmware/application/ui_sd_card_status_view.hpp @@ -23,6 +23,7 @@ #ifndef __UI_SD_CARD_STATUS_VIEW_H__ #define __UI_SD_CARD_STATUS_VIEW_H__ +#include "theme.hpp" #include "ui_widget.hpp" #include "sd_card.hpp" diff --git a/firmware/application/usb_serial_shell.cpp b/firmware/application/usb_serial_shell.cpp index e260b8b8..722eef46 100644 --- a/firmware/application/usb_serial_shell.cpp +++ b/firmware/application/usb_serial_shell.cpp @@ -107,13 +107,13 @@ static void cmd_sd_over_usb(BaseSequentialStream* chp, int argc, char* argv[]) { ui::Painter painter; painter.fill_rectangle( {0, 0, portapack::display.width(), portapack::display.height()}, - ui::Color::black()); + Theme::getInstance()->fg_yellow->background); painter.draw_bitmap( {portapack::display.width() / 2 - 8, portapack::display.height() / 2 - 8}, ui::bitmap_icon_hackrf, - ui::Color::yellow(), - ui::Color::black()); + Theme::getInstance()->fg_yellow->foreground, + Theme::getInstance()->fg_yellow->background); sdcDisconnect(&SDCD1); sdcStop(&SDCD1); diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index f867fdad..866ec45b 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -32,7 +32,6 @@ #include "portapack.hpp" #include "string_format.hpp" #include "ui.hpp" -#include "ui_styles.hpp" #include "ui_painter.hpp" #include "ui_flash_utility.hpp" #include "utility.hpp" @@ -139,7 +138,7 @@ struct ui_config2_t { bool UNUSED_5 : 1; bool UNUSED_6 : 1; - uint8_t PLACEHOLDER_2; + uint8_t theme_id; uint8_t PLACEHOLDER_3; }; static_assert(sizeof(ui_config2_t) == sizeof(uint32_t)); @@ -962,6 +961,10 @@ bool ui_hide_battery_icon() { return data->ui_config2.hide_battery_icon; } +uint8_t ui_theme_id() { + return data->ui_config2.theme_id; +} + void set_ui_hide_speaker(bool v) { data->ui_config2.hide_speaker = v; } @@ -1000,6 +1003,9 @@ void set_ui_hide_numeric_battery(bool v) { void set_ui_hide_battery_icon(bool v) { data->ui_config2.hide_battery_icon = v; } +void set_ui_theme_id(uint8_t theme_id) { + data->ui_config2.theme_id = theme_id; +} /* Converter */ bool config_converter() { @@ -1170,13 +1176,13 @@ bool debug_dump() { ensure_directory(debug_dir); filename = next_filename_matching_pattern(debug_dir + "/DEBUG_DUMP_????.TXT"); if (filename.empty()) { - painter.draw_string({0, 320 - 16}, ui::Styles::red, "COULD NOT GET DUMP NAME !"); + painter.draw_string({0, 320 - 16}, *ui::Theme::getInstance()->fg_red, "COULD NOT GET DUMP NAME !"); return false; } // dump data fo filename auto error = pmem_dump_file.create(filename); if (error) { - painter.draw_string({0, 320 - 16}, ui::Styles::red, "ERROR DUMPING " + filename.filename().string() + " !"); + painter.draw_string({0, 320 - 16}, *ui::Theme::getInstance()->fg_red, "ERROR DUMPING " + filename.filename().string() + " !"); return false; } pmem_dump_file.write_line("FW version: " VERSION_STRING); @@ -1264,6 +1270,7 @@ bool debug_dump() { pmem_dump_file.write_line("ui_config2 hide_fake_brightness: " + to_string_dec_uint(data->ui_config2.hide_fake_brightness)); pmem_dump_file.write_line("ui_config2 hide_battery_icon: " + to_string_dec_uint(data->ui_config2.hide_battery_icon)); pmem_dump_file.write_line("ui_config2 hide_numeric_battery: " + to_string_dec_uint(data->ui_config2.hide_numeric_battery)); + pmem_dump_file.write_line("ui_config2 theme_id: " + to_string_dec_uint(data->ui_config2.theme_id)); // misc_config bits pmem_dump_file.write_line("misc_config config_audio_mute: " + to_string_dec_int(config_audio_mute())); @@ -1317,7 +1324,7 @@ bool debug_dump() { pmem_dump_file.write_line("tx_gain: " + to_string_dec_int(transmitter_model.tx_gain())); pmem_dump_file.write_line("channel_bandwidth: " + to_string_dec_uint(transmitter_model.channel_bandwidth())); // on screen information - 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; } diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 3a042ccb..ae4ec687 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -338,6 +338,7 @@ bool ui_hide_fake_brightness(); bool ui_hide_numeric_battery(); bool ui_hide_battery_icon(); bool ui_hide_sd_card(); +uint8_t ui_theme_id(); void set_ui_hide_speaker(bool v); void set_ui_hide_mute(bool v); void set_ui_hide_converter(bool v); @@ -350,6 +351,7 @@ void set_ui_hide_fake_brightness(bool v); void set_ui_hide_numeric_battery(bool v); void set_ui_hide_battery_icon(bool v); void set_ui_hide_sd_card(bool v); +void set_ui_theme_id(uint8_t v); // sd persisting settings bool should_use_sdcard_for_pmem(); diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index 588d4b18..294041a4 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -526,7 +526,7 @@ void BigFrequency::paint(Painter& painter) { // Erase painter.fill_rectangle( {{0, rect.location().y()}, {screen_width, 52}}, - ui::Color::black()); + Theme::getInstance()->bg_darkest->background); // Prepare digits if (!_frequency) { @@ -634,7 +634,7 @@ ActivityDot::ActivityDot( _color{color} {} void ActivityDot::paint(Painter& painter) { - painter.fill_rectangle(screen_rect(), _on ? _color : Color::grey()); + painter.fill_rectangle(screen_rect(), _on ? _color : Theme::getInstance()->bg_medium->background); } void ActivityDot::toggle() { @@ -661,7 +661,7 @@ void Console::clear(bool clear_buffer = false) { if (!hidden() && visible()) { display.fill_rectangle( screen_rect(), - Color::black()); + Theme::getInstance()->bg_darkest->background); } pos = {0, 0}; @@ -857,12 +857,12 @@ void Checkbox::paint(Painter& painter) { if (value_ == true) { // Check - portapack::display.draw_line({x + 2, y + 14}, {x + 6, y + 18}, ui::Color::green()); - portapack::display.draw_line({x + 6, y + 18}, {x + 20, y + 4}, ui::Color::green()); + portapack::display.draw_line({x + 2, y + 14}, {x + 6, y + 18}, Theme::getInstance()->fg_green->foreground); + portapack::display.draw_line({x + 6, y + 18}, {x + 20, y + 4}, Theme::getInstance()->fg_green->foreground); } else { // Cross - portapack::display.draw_line({x + 1, y + 1}, {x + 24 - 2, y + 24 - 2}, ui::Color::red()); - portapack::display.draw_line({x + 24 - 2, y + 1}, {x + 1, y + 24 - 2}, ui::Color::red()); + portapack::display.draw_line({x + 1, y + 1}, {x + 24 - 2, y + 24 - 2}, Theme::getInstance()->fg_red->foreground); + portapack::display.draw_line({x + 24 - 2, y + 1}, {x + 1, y + 24 - 2}, Theme::getInstance()->fg_red->foreground); } painter.draw_string( @@ -880,12 +880,12 @@ void Checkbox::paint(Painter& painter) { if (value_ == true) { // Check - portapack::display.draw_line({x + 2, y + 8}, {x + 6, y + 12}, ui::Color::green()); - portapack::display.draw_line({x + 6, y + 12}, {x + 13, y + 5}, ui::Color::green()); + portapack::display.draw_line({x + 2, y + 8}, {x + 6, y + 12}, Theme::getInstance()->fg_green->foreground); + portapack::display.draw_line({x + 6, y + 12}, {x + 13, y + 5}, Theme::getInstance()->fg_green->foreground); } else { // Cross - portapack::display.draw_line({x + 1, y + 1}, {x + 16 - 2, y + 16 - 2}, ui::Color::red()); - portapack::display.draw_line({x + 16 - 2, y + 1}, {x + 1, y + 16 - 2}, ui::Color::red()); + portapack::display.draw_line({x + 1, y + 1}, {x + 16 - 2, y + 16 - 2}, Theme::getInstance()->fg_red->foreground); + portapack::display.draw_line({x + 16 - 2, y + 1}, {x + 1, y + 16 - 2}, Theme::getInstance()->fg_red->foreground); } painter.draw_string( @@ -963,17 +963,17 @@ void Button::paint(Painter& painter) { if (has_focus() || highlighted()) { bg = style().foreground; - fg = Color::black(); + fg = Theme::getInstance()->bg_darkest->background; } else { - bg = Color::grey(); + bg = Theme::getInstance()->bg_medium->background; fg = style().foreground; } const Style paint_style = {style().font, bg, fg}; - painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey()); - painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey()); - painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey()); + painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Theme::getInstance()->fg_light->foreground); + painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Theme::getInstance()->bg_dark->background); + painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Theme::getInstance()->bg_dark->background); painter.fill_rectangle( {r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2}, @@ -1116,17 +1116,17 @@ void ButtonWithEncoder::paint(Painter& painter) { if (has_focus() || highlighted()) { bg = style().foreground; - fg = Color::black(); + fg = Theme::getInstance()->bg_darkest->background; } else { - bg = Color::grey(); + bg = Theme::getInstance()->bg_medium->background; fg = style().foreground; } const Style paint_style = {style().font, bg, fg}; - painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey()); - painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey()); - painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey()); + painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Theme::getInstance()->fg_light->foreground); + painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Theme::getInstance()->bg_dark->background); + painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Theme::getInstance()->bg_dark->background); painter.fill_rectangle( {r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2}, @@ -1244,7 +1244,7 @@ NewButton::NewButton( Rect parent_rect, std::string text, const Bitmap* bitmap) - : NewButton{parent_rect, text, bitmap, Color::dark_cyan()} {} + : NewButton{parent_rect, text, bitmap, Theme::getInstance()->fg_darkcyan->foreground} {} NewButton::NewButton( Rect parent_rect, @@ -1311,9 +1311,9 @@ void NewButton::paint(Painter& painter) { const auto r = screen_rect(); const Style style = paint_style(); - painter.draw_rectangle({r.location(), {r.width(), 1}}, Color::light_grey()); - painter.draw_rectangle({r.left(), r.top() + r.height() - 1, r.width(), 1}, Color::dark_grey()); - painter.draw_rectangle({r.left() + r.width() - 1, r.top(), 1, r.height()}, Color::dark_grey()); + painter.draw_rectangle({r.location(), {r.width(), 1}}, Theme::getInstance()->fg_light->foreground); + painter.draw_rectangle({r.left(), r.top() + r.height() - 1, r.width(), 1}, Theme::getInstance()->bg_dark->background); + painter.draw_rectangle({r.left() + r.width() - 1, r.top(), 1, r.height()}, Theme::getInstance()->bg_dark->background); painter.fill_rectangle( {r.left(), r.top() + 1, r.width() - 1, r.height() - 2}, @@ -1346,7 +1346,7 @@ Style NewButton::paint_style() { if (has_focus() || highlighted()) { s.background = style().foreground; - s.foreground = Color::black(); + s.foreground = Theme::getInstance()->bg_darkest->background; } else { s.background = bg_color_; s.foreground = style().foreground; @@ -1408,7 +1408,7 @@ bool NewButton::on_touch(const TouchEvent event) { /* Image *****************************************************************/ Image::Image() - : Image{{}, nullptr, Color::white(), Color::black()} { + : Image{{}, nullptr, Theme::getInstance()->bg_darkest->foreground, Theme::getInstance()->bg_darkest->background} { } Image::Image( @@ -1525,9 +1525,9 @@ ImageToggle::ImageToggle( const Bitmap* bitmap_) : ImageToggle{parent_rect, bitmap_, - Color::green(), - Color::light_grey(), - Color::dark_grey()} {} + Theme::getInstance()->fg_green->foreground, + Theme::getInstance()->fg_light->foreground, + Theme::getInstance()->bg_dark->background} {} ImageToggle::ImageToggle( Rect parent_rect, @@ -1786,7 +1786,7 @@ void OptionsField::set_options(options_t new_options) { void OptionsField::paint(Painter& painter) { const auto paint_style = has_focus() ? style().invert() : style(); - painter.fill_rectangle({screen_rect().location(), {(int)length_ * 8, 16}}, ui::Color::black()); + painter.fill_rectangle({screen_rect().location(), {(int)length_ * 8, 16}}, Theme::getInstance()->bg_darkest->background); if (selected_index() < options_.size()) { std::string_view temp = selected_index_name(); @@ -2086,9 +2086,9 @@ bool BatteryIcon::on_touch(TouchEvent event) { return false; } void BatteryIcon::paint(Painter& painter) { - ui::Rect rect = screen_rect(); // 10, 1 * 16 - painter.fill_rectangle(rect, has_focus() || highlighted() ? Color::light_grey() : Color::dark_grey()); // clear - ui::Color battColor = (charge_) ? Color::cyan() : Color::green(); + ui::Rect rect = screen_rect(); // 10, 1 * 16 + painter.fill_rectangle(rect, has_focus() || highlighted() ? Theme::getInstance()->fg_light->foreground : Theme::getInstance()->bg_dark->background); // clear + ui::Color battColor = (charge_) ? Theme::getInstance()->fg_blue->foreground : Theme::getInstance()->fg_green->foreground; // batt body: painter.draw_vline({rect.left() + 1, rect.top() + 2}, rect.height() - 4, battColor); painter.draw_vline({rect.right() - 2, rect.top() + 2}, rect.height() - 4, battColor); @@ -2098,7 +2098,7 @@ void BatteryIcon::paint(Painter& painter) { painter.draw_hline({rect.left() + 3, rect.top() + 1}, rect.width() - 6, battColor); painter.draw_hline({rect.left() + 3, 0}, rect.width() - 6, battColor); if (percent_ > 100) { // error / unk - painter.draw_string({rect.left() + 2, rect.top() + 3}, font::fixed_5x8, Color::white(), Color::dark_grey(), "?"); + painter.draw_string({rect.left() + 2, rect.top() + 3}, font::fixed_5x8, Theme::getInstance()->bg_dark->foreground, Theme::getInstance()->bg_dark->background, "?"); return; } int8_t ppx = (rect.bottom() - 3) - (rect.top() + 2); // 11px max height to draw bars @@ -2106,11 +2106,11 @@ void BatteryIcon::paint(Painter& painter) { int8_t pp = ppx - ptd; // pixels to start from if (percent_ >= 70) - battColor = Color::green(); + battColor = Theme::getInstance()->fg_green->foreground; else if (percent_ >= 40) - battColor = Color::orange(); + battColor = Theme::getInstance()->fg_orange->foreground; else - battColor = Color::red(); + battColor = Theme::getInstance()->fg_red->foreground; // fill the bars for (int y = pp; y < ppx; y++) { painter.draw_hline({rect.left() + 2, rect.top() + 3 + y}, rect.width() - 4, battColor); @@ -2126,7 +2126,7 @@ BatteryTextField::BatteryTextField(Rect parent_rect, uint8_t percent) } void BatteryTextField::paint(Painter& painter) { - Color bg = has_focus() || highlighted() ? Color::light_grey() : Color::dark_grey(); + Color bg = has_focus() || highlighted() ? Theme::getInstance()->fg_light->foreground : Theme::getInstance()->bg_dark->background; ui::Rect rect = screen_rect(); // 2 * 8, 1 * 16 painter.fill_rectangle(rect, bg); // clear std::string txt_batt = percent_ <= 100 ? to_string_dec_uint(percent_) : "UNK"; @@ -2135,8 +2135,8 @@ void BatteryTextField::paint(Painter& painter) { xdelta = 5; else if (txt_batt.length() == 2) xdelta = 2; - painter.draw_string({rect.left() + xdelta, rect.top()}, font::fixed_5x8, Color::white(), bg, txt_batt); - painter.draw_string({rect.left(), rect.top() + 8}, font::fixed_5x8, Color::white(), bg, (charge_) ? "+%" : " %"); + painter.draw_string({rect.left() + xdelta, rect.top()}, font::fixed_5x8, Theme::getInstance()->bg_dark->foreground, bg, txt_batt); + painter.draw_string({rect.left(), rect.top() + 8}, font::fixed_5x8, Theme::getInstance()->bg_dark->foreground, bg, (charge_) ? "+%" : " %"); } void BatteryTextField::getAccessibilityText(std::string& result) { @@ -2445,8 +2445,8 @@ void SymField::paint(Painter& painter) { if (editing_ && n == selected_) { // Use 'bg_blue' style to indicate in editing mode. - paint_style.foreground = Color::white(); - paint_style.background = Color::blue(); + paint_style.foreground = Theme::getInstance()->bg_darkest->foreground; + paint_style.background = Theme::getInstance()->fg_blue->foreground; } } @@ -2631,7 +2631,7 @@ void Waveform::paint(Painter& painter) { x_inc = (float)screen_rect().size().width() / length_; // Clear - painter.fill_rectangle_unrolled8(screen_rect(), Color::black()); + painter.fill_rectangle_unrolled8(screen_rect(), Theme::getInstance()->bg_darkest->background); if (digital_) { // Digital waveform: each value is an horizontal line @@ -2724,13 +2724,13 @@ void VuMeter::paint(Painter& painter) { lit = true; if (bar == 0) - color = lit ? Color::red() : Color::dark_grey(); + color = lit ? Theme::getInstance()->fg_red->foreground : Theme::getInstance()->bg_dark->background; else if (bar == 1) - color = lit ? Color::orange() : Color::dark_grey(); + color = lit ? Theme::getInstance()->fg_orange->foreground : Theme::getInstance()->bg_dark->background; else if ((bar == 2) || (bar == 3)) - color = lit ? Color::yellow() : Color::dark_grey(); + color = lit ? Theme::getInstance()->fg_yellow->foreground : Theme::getInstance()->bg_dark->background; else - color = lit ? Color::green() : Color::dark_grey(); + color = lit ? Theme::getInstance()->fg_green->foreground : Theme::getInstance()->bg_dark->background; painter.fill_rectangle({pos.x(), pos.y() + (Coord)(bar * (LED_height + 1)), width, (Coord)LED_height}, color); } @@ -2752,8 +2752,8 @@ void VuMeter::paint(Painter& painter) { // Draw max level if (max != prev_max) { - painter.draw_hline({marks_x, bottom - (height * prev_max) / 256}, 8, Color::black()); - painter.draw_hline({marks_x, bottom - (height * max) / 256}, 8, Color::white()); + painter.draw_hline({marks_x, bottom - (height * prev_max) / 256}, 8, Theme::getInstance()->bg_darkest->background); + painter.draw_hline({marks_x, bottom - (height * max) / 256}, 8, Theme::getInstance()->bg_darkest->foreground); if (prev_max == mark) prev_mark = 0; // Force mark refresh prev_max = max; @@ -2762,8 +2762,8 @@ void VuMeter::paint(Painter& painter) { // Draw mark (forced refresh) if (mark) { - painter.draw_hline({marks_x, bottom - (height * prev_mark) / 256}, 8, Color::black()); - painter.draw_hline({marks_x, bottom - (height * mark) / 256}, 8, Color::grey()); + painter.draw_hline({marks_x, bottom - (height * prev_mark) / 256}, 8, Theme::getInstance()->bg_darkest->background); + painter.draw_hline({marks_x, bottom - (height * mark) / 256}, 8, Theme::getInstance()->fg_medium->foreground); prev_mark = mark; } } diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index e1e65f2e..f12b2734 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -525,7 +525,7 @@ class NewButton : public Widget { protected: virtual Style paint_style(); Color color_; - Color bg_color_{Color::grey()}; + Color bg_color_{Theme::getInstance()->bg_medium->background}; private: std::string text_; @@ -641,7 +641,7 @@ class ImageOptionsField : public Widget { options_t options); ImageOptionsField() - : ImageOptionsField{{}, Color::white(), Color::black(), {}} { + : ImageOptionsField{{}, Theme::getInstance()->bg_darkest->foreground, Theme::getInstance()->bg_darkest->background, {}} { } void set_options(options_t new_options); @@ -803,10 +803,10 @@ class BatteryTextField : public Widget { uint8_t percent_{102}; bool charge_{false}; - static constexpr Style style{ + Style style{ .font = font::fixed_5x8, - .background = Color::dark_grey(), - .foreground = Color::white(), + .background = Theme::getInstance()->bg_dark->background, + .foreground = Theme::getInstance()->bg_dark->foreground, }; }; @@ -980,7 +980,7 @@ class Waveform : public Widget { void paint(Painter& painter) override; private: - const Color cursor_colors[2] = {Color::cyan(), Color::magenta()}; + const Color cursor_colors[2] = {Theme::getInstance()->fg_cyan->foreground, Theme::getInstance()->fg_magenta->foreground}; int16_t* data_; uint32_t length_;