diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 5c50dbace..2db3f7dfa 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -186,7 +186,7 @@ void AISRecentEntry::update(const ais::Packet& packet) { namespace ui { template<> -void RecentEntriesView::draw( +void RecentEntriesTable::draw( const Entry& entry, const Rect& target_rect, Painter& painter, diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 8c1b305f7..108c7937b 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -76,7 +76,7 @@ void ERTRecentEntry::update(const ert::Packet& packet) { namespace ui { template<> -void RecentEntriesView::draw( +void RecentEntriesTable::draw( const Entry& entry, const Rect& target_rect, Painter& painter, diff --git a/firmware/application/recent_entries.hpp b/firmware/application/recent_entries.hpp index 795bf602c..fc2c08ca9 100644 --- a/firmware/application/recent_entries.hpp +++ b/firmware/application/recent_entries.hpp @@ -95,19 +95,8 @@ namespace ui { using RecentEntriesColumn = std::pair; -template -class RecentEntriesView : public View { +class RecentEntriesHeader : public Widget { public: - using Entry = typename Entries::value_type; - - std::function on_select; - - RecentEntriesView( - Entries& recent - ) : recent { recent } - { - set_focusable(true); - } template void set_columns( @@ -119,6 +108,47 @@ public: } } + void paint(Painter& painter) override { + const auto r = screen_rect(); + const auto& parent_style = style(); + + const Style style { + .font = parent_style.font, + .background = Color::blue(), + .foreground = parent_style.foreground, + }; + + auto p = r.pos; + for(const auto& column : _columns) { + const auto width = column.second; + auto text = column.first; + if( width > text.length() ) { + text.append(width - text.length(), ' '); + } + + painter.draw_string(p, style, text); + p += { static_cast((width * 8) + 8), 0 }; + } + } + +private: + std::vector _columns; +}; + +template +class RecentEntriesTable : public Widget { +public: + using Entry = typename Entries::value_type; + + std::function on_select; + + RecentEntriesTable( + Entries& recent + ) : recent { recent } + { + set_focusable(true); + } + void paint(Painter& painter) override { const auto r = screen_rect(); const auto& s = style(); @@ -126,15 +156,6 @@ public: Rect target_rect { r.pos, { r.width(), s.font.line_height() }}; const size_t visible_item_count = r.height() / s.font.line_height(); - const Style style_header { - .font = font::fixed_8x16, - .background = Color::blue(), - .foreground = Color::white(), - }; - - draw_header(target_rect, painter, style_header); - target_rect.pos.y += target_rect.height(); - auto selected = find(recent, selected_key); if( selected == std::end(recent) ) { selected = std::begin(recent); @@ -180,7 +201,6 @@ public: private: Entries& recent; - std::vector> _columns; using EntryKey = typename Entry::Key; EntryKey selected_key = Entry::invalid_key; @@ -211,24 +231,6 @@ private: set_dirty(); } - void draw_header( - const Rect& target_rect, - Painter& painter, - const Style& style - ) { - auto x = 0; - for(const auto& column : _columns) { - const auto width = column.second; - auto text = column.first; - if( width > text.length() ) { - text.append(width - text.length(), ' '); - } - - painter.draw_string({ x, target_rect.pos.y }, style, text); - x += (width * 8) + 8; - } - } - void draw( const Entry& entry, const Rect& target_rect, @@ -237,6 +239,58 @@ private: ); }; +template +class RecentEntriesView : public View { +public: + using Entry = typename Entries::value_type; + + std::function on_select; + + RecentEntriesView( + Entries& recent + ) : _table { recent } + { + add_children({ { + &_header, + &_table, + } }); + + _table.on_select = [this](const Entry& entry) { if( this->on_select ) { this->on_select(entry); } }; + } + + template + void set_columns( + const std::array& columns + ) { + _header.set_columns(columns); + } + + void set_parent_rect(const Rect new_parent_rect) override { + constexpr Dim scale_height = 16; + + View::set_parent_rect(new_parent_rect); + _header.set_parent_rect({ 0, 0, new_parent_rect.width(), scale_height }); + _table.set_parent_rect({ + 0, scale_height, + new_parent_rect.width(), + new_parent_rect.height() - scale_height + }); + } + + void paint(Painter&) override { + // Children completely cover this View, do not paint. + // TODO: What happens here shouldn't matter if I do proper damage detection! + } + + void on_focus() override { + _table.focus(); + } + +private: + RecentEntriesHeader _header; + RecentEntriesTable _table; +}; + } /* namespace ui */ #endif/*__RECENT_ENTRIES_H__*/ diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index c435bce14..e7f38e371 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -96,7 +96,7 @@ void TPMSRecentEntry::update(const tpms::Reading& reading) { namespace ui { template<> -void RecentEntriesView::draw( +void RecentEntriesTable::draw( const Entry& entry, const Rect& target_rect, Painter& painter,