diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 385d857b..0242baa2 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -63,9 +63,41 @@ void ERTLogger::on_packet(const ert::Packet& packet) { } } +void ERTRecentEntry::update(const ert::Packet& packet) { + received_count++; + + last_consumption = packet.consumption(); +} + namespace ui { -ERTView::ERTView() { +template<> +void RecentEntriesView::draw( + const Entry& entry, + const Rect& target_rect, + Painter& painter, + const Style& style, + const bool is_selected +) { + const auto& draw_style = is_selected ? style.invert() : style; + + std::string line = ert::format::id(entry.id) + " " + ert::format::consumption(entry.last_consumption); + + if( entry.received_count > 999 ) { + line += " +++"; + } else { + line += " " + to_string_dec_uint(entry.received_count, 3); + } + + line.resize(target_rect.width() / 8, ' '); + painter.draw_string(target_rect.pos, draw_style, line); +} + +ERTAppView::ERTAppView() { + add_children({ { + &recent_entries_view, + } }); + EventDispatcher::message_map().register_handler(Message::ID::ERTPacket, [this](Message* const p) { const auto message = static_cast(p); @@ -82,29 +114,27 @@ ERTView::ERTView() { receiver_model.set_baseband_bandwidth(2500000); } -ERTView::~ERTView() { +ERTAppView::~ERTAppView() { EventDispatcher::message_map().unregister_handler(Message::ID::ERTPacket); } -void ERTView::on_packet(const ert::Packet& packet) { +void ERTAppView::set_parent_rect(const Rect new_parent_rect) { + View::set_parent_rect(new_parent_rect); + recent_entries_view.set_parent_rect({ 0, 0, new_parent_rect.width(), new_parent_rect.height() }); +} + +void ERTAppView::on_packet(const ert::Packet& packet) { logger.on_packet(packet); if( packet.crc_ok() ) { - std::string msg { ert::format::type(packet.type()) }; - - switch(packet.type()) { - case ert::Packet::Type::SCM: - case ert::Packet::Type::IDM: - msg += " " + ert::format::id(packet.id()); - msg += " " + ert::format::consumption(packet.consumption()); - break; - - default: - break; - } - - writeln(msg); + recent.on_packet(packet.id(), packet); + recent_entries_view.set_dirty(); } } +void ERTAppView::on_show_list() { + recent_entries_view.hidden(false); + recent_entries_view.focus(); +} + } /* namespace ui */ diff --git a/firmware/application/ert_app.hpp b/firmware/application/ert_app.hpp index 46c2d15a..8614b076 100644 --- a/firmware/application/ert_app.hpp +++ b/firmware/application/ert_app.hpp @@ -22,14 +22,39 @@ #ifndef __ERT_APP_H__ #define __ERT_APP_H__ -#include "ui_console.hpp" #include "log_file.hpp" #include "ert_packet.hpp" +#include "recent_entries.hpp" + #include #include -#include + +struct ERTRecentEntry { + using Key = ert::ID; + + // TODO: Is this the right choice of invalid key value? + static constexpr Key invalid_key = 0; + + ert::ID id { invalid_key }; + + size_t received_count { 0 }; + + ert::Consumption last_consumption; + + ERTRecentEntry( + const Key& key + ) : id { key } + { + } + + Key key() const { + return id; + } + + void update(const ert::Packet& packet); +}; class ERTLogger { public: @@ -39,17 +64,31 @@ private: LogFile log_file { "ert.txt" }; }; +using ERTRecentEntries = RecentEntries; + namespace ui { -class ERTView : public Console { +using ERTRecentEntriesView = RecentEntriesView; + +class ERTAppView : public View { public: - ERTView(); - ~ERTView(); + ERTAppView(); + ~ERTAppView(); + + void set_parent_rect(const Rect new_parent_rect) override; + + // Prevent painting of region covered entirely by a child. + // TODO: Add flag to View that specifies view does not need to be cleared before painting. + void paint(Painter&) override { }; private: + ERTRecentEntries recent; ERTLogger logger; + ERTRecentEntriesView recent_entries_view { recent }; + void on_packet(const ert::Packet& packet); + void on_show_list(); }; } /* namespace ui */ diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 11c03150..82e7c4bd 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -529,7 +529,7 @@ void ReceiverView::on_modulation_changed(ReceiverModel::Mode mode) { break; case ReceiverModel::Mode::ERT: - widget_content = std::make_unique(); + widget_content = std::make_unique(); break; default: