From 8047231c5b5970f2ca6e111643e2f8809ec64135 Mon Sep 17 00:00:00 2001 From: mverch67 Date: Tue, 17 Sep 2024 21:37:18 +0200 Subject: [PATCH] packet statistics table --- generated/ui_320x240/screens.c | 31 ++++-- generated/ui_320x240/screens.h | 2 +- generated/ui_320x240/styles.c | 46 ++++++++ generated/ui_320x240/styles.h | 6 + include/TFTView_320x240.h | 2 + include/Themes.h | 1 + include/lv_conf.h | 2 +- source/TFTView_320x240.cpp | 198 ++++++++++++++++++++++++++++++++- source/Themes.cpp | 44 +++++++- 9 files changed, 309 insertions(+), 23 deletions(-) diff --git a/generated/ui_320x240/screens.c b/generated/ui_320x240/screens.c index 048447b..13df72a 100644 --- a/generated/ui_320x240/screens.c +++ b/generated/ui_320x240/screens.c @@ -2232,7 +2232,7 @@ void create_screen_main_screen() { lv_obj_set_pos(obj, 25, 0); lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_label_set_long_mode(obj, LV_LABEL_LONG_SCROLL_CIRCULAR); - lv_label_set_text(obj, _("Statistics")); + lv_label_set_text(obj, _("Packet Statistics")); lv_obj_set_style_align(obj, LV_ALIGN_LEFT_MID, LV_PART_MAIN | LV_STATE_DEFAULT); } { @@ -4851,26 +4851,33 @@ void create_screen_main_screen() { lv_obj_set_size(obj, LV_PCT(88), LV_PCT(90)); lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN|LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN_HOR|LV_OBJ_FLAG_SCROLL_CHAIN_VER); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_OFF); add_style_panel_style(obj); lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_left(obj, 8, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_row(obj, 5, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_column(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_top(obj, 8, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_bottom(obj, 8, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(obj, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_layout(obj, LV_LAYOUT_FLEX, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_flex_flow(obj, LV_FLEX_FLOW_COLUMN, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_pad_right(obj, 14, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 2, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); { lv_obj_t *parent_obj = obj; { - // StatisticsLabel - lv_obj_t *obj = lv_label_create(parent_obj); - objects.statistics_label = obj; + // StatisticsTable + lv_obj_t *obj = lv_table_create(parent_obj); + objects.statistics_table = obj; lv_obj_set_pos(obj, 0, 0); - lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); - lv_label_set_text(obj, ""); + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); + lv_obj_set_scroll_dir(obj, LV_DIR_VER); + add_style_statistics_table_style(obj); + lv_obj_set_style_pad_top(obj, 1, LV_PART_ITEMS | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 1, LV_PART_ITEMS | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(obj, 1, LV_PART_ITEMS | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 1, LV_PART_ITEMS | LV_STATE_DEFAULT); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_ITEMS | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 2, LV_PART_MAIN | LV_STATE_DEFAULT); } } } diff --git a/generated/ui_320x240/screens.h b/generated/ui_320x240/screens.h index d30a8cc..d6e1902 100644 --- a/generated/ui_320x240/screens.h +++ b/generated/ui_320x240/screens.h @@ -372,7 +372,7 @@ typedef struct _objects_t { lv_obj_t *signal_scanner_start_label; lv_obj_t *snr_slider; lv_obj_t *start_button_panel; - lv_obj_t *statistics_label; + lv_obj_t *statistics_table; lv_obj_t *tab_page_basic_settings; lv_obj_t *tab_page_filter; lv_obj_t *tab_page_highlight; diff --git a/generated/ui_320x240/styles.c b/generated/ui_320x240/styles.c index b63035b..6c2eb07 100644 --- a/generated/ui_320x240/styles.c +++ b/generated/ui_320x240/styles.c @@ -749,6 +749,50 @@ void remove_style_positive_image_style(lv_obj_t *obj) { lv_obj_remove_style(obj, get_style_positive_image_style_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT); }; +// +// Style: StatisticsTableStyle +// + +void init_style_statistics_table_style_MAIN_DEFAULT(lv_style_t *style) { + lv_style_set_text_font(style, &ui_font_montserrat_12); +}; + +lv_style_t *get_style_statistics_table_style_MAIN_DEFAULT() { + static lv_style_t *style; + if (!style) { + style = lv_malloc(sizeof(lv_style_t)); + lv_style_init(style); + init_style_statistics_table_style_MAIN_DEFAULT(style); + } + return style; +}; + +void init_style_statistics_table_style_ITEMS_DEFAULT(lv_style_t *style) { + lv_style_set_bg_color(style, lv_color_hex(0xfff4f4f0)); + lv_style_set_text_color(style, lv_color_hex(0xff212121)); + lv_style_set_border_color(style, lv_color_hex(0xffe0e0e0)); +}; + +lv_style_t *get_style_statistics_table_style_ITEMS_DEFAULT() { + static lv_style_t *style; + if (!style) { + style = lv_malloc(sizeof(lv_style_t)); + lv_style_init(style); + init_style_statistics_table_style_ITEMS_DEFAULT(style); + } + return style; +}; + +void add_style_statistics_table_style(lv_obj_t *obj) { + lv_obj_add_style(obj, get_style_statistics_table_style_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_add_style(obj, get_style_statistics_table_style_ITEMS_DEFAULT(), LV_PART_ITEMS | LV_STATE_DEFAULT); +}; + +void remove_style_statistics_table_style(lv_obj_t *obj) { + lv_obj_remove_style(obj, get_style_statistics_table_style_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_remove_style(obj, get_style_statistics_table_style_ITEMS_DEFAULT(), LV_PART_ITEMS | LV_STATE_DEFAULT); +}; + // // // @@ -780,6 +824,7 @@ void add_style(lv_obj_t *obj, int32_t styleIndex) { add_style_spinner_style, add_style_settings_label_style, add_style_positive_image_style, + add_style_statistics_table_style, }; add_style_funcs[styleIndex](obj); } @@ -811,6 +856,7 @@ void remove_style(lv_obj_t *obj, int32_t styleIndex) { remove_style_spinner_style, remove_style_settings_label_style, remove_style_positive_image_style, + remove_style_statistics_table_style, }; remove_style_funcs[styleIndex](obj); } diff --git a/generated/ui_320x240/styles.h b/generated/ui_320x240/styles.h index 058724f..97afe31 100644 --- a/generated/ui_320x240/styles.h +++ b/generated/ui_320x240/styles.h @@ -134,6 +134,12 @@ lv_style_t *get_style_positive_image_style_MAIN_DEFAULT(); void add_style_positive_image_style(lv_obj_t *obj); void remove_style_positive_image_style(lv_obj_t *obj); +// Style: StatisticsTableStyle +lv_style_t *get_style_statistics_table_style_MAIN_DEFAULT(); +lv_style_t *get_style_statistics_table_style_ITEMS_DEFAULT(); +void add_style_statistics_table_style(lv_obj_t *obj); +void remove_style_statistics_table_style(lv_obj_t *obj); + #ifdef __cplusplus diff --git a/include/TFTView_320x240.h b/include/TFTView_320x240.h index 6c0403c..508821e 100644 --- a/include/TFTView_320x240.h +++ b/include/TFTView_320x240.h @@ -197,6 +197,7 @@ class TFTView_320x240 : public MeshtasticView void removeSpinner(void); void packetDetected(const meshtastic_MeshPacket &p); void writePacketLog(const meshtastic_MeshPacket &p); + void updateStatistics(const meshtastic_MeshPacket &p); // lvgl event callbacks // static void ui_event_HomeButton(lv_event_t * e); @@ -268,6 +269,7 @@ class TFTView_320x240 : public MeshtasticView static void ui_event_packet_log(lv_event_t *e); static void ui_event_pin_screen_button(lv_event_t *e); + static void ui_event_statistics_table(lv_event_t *e); static void ui_event_ok(lv_event_t *e); static void ui_event_cancel(lv_event_t *e); diff --git a/include/Themes.h b/include/Themes.h index 5c47ac5..6f6d34b 100644 --- a/include/Themes.h +++ b/include/Themes.h @@ -15,6 +15,7 @@ class Themes static void recolorButton(lv_obj_t* obj, bool enabled, lv_opa_t opa = 255); static void recolorText(lv_obj_t* obj, bool enabled); static void recolorTopLabel(lv_obj_t* obj, bool alert); + static void recolorTableRow(lv_draw_fill_dsc_t* fill_draw_dsc, bool odd); private: Themes(void) = default; diff --git a/include/lv_conf.h b/include/lv_conf.h index 17395b7..e95ddb1 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -578,7 +578,7 @@ #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ #endif -#define LV_USE_TABLE 0 +#define LV_USE_TABLE 1 #define LV_USE_TABVIEW 1 diff --git a/source/TFTView_320x240.cpp b/source/TFTView_320x240.cpp index a36a4b6..9be5fc3 100644 --- a/source/TFTView_320x240.cpp +++ b/source/TFTView_320x240.cpp @@ -265,6 +265,28 @@ void TFTView_320x240::apply_hotfix(void) lv_obj_add_flag(objects.detected_node_button, LV_OBJ_FLAG_HIDDEN); lv_label_set_text(objects.detector_start_label, "Start"); lv_obj_clear_flag(objects.detector_start_button_panel, LV_OBJ_FLAG_HIDDEN); + + // add event callback to to apply custom drawing for statistics table + lv_obj_add_event_cb(objects.statistics_table, ui_event_statistics_table, LV_EVENT_DRAW_TASK_ADDED, NULL); + lv_obj_add_flag(objects.statistics_table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + // statistics table item size + lv_table_set_row_count(objects.statistics_table, 12); + lv_table_set_column_count(objects.statistics_table, 7); + lv_table_set_column_width(objects.statistics_table, 0, 57); + lv_table_set_column_width(objects.statistics_table, 1, 36); + lv_table_set_column_width(objects.statistics_table, 2, 36); + lv_table_set_column_width(objects.statistics_table, 3, 36); + lv_table_set_column_width(objects.statistics_table, 4, 36); + lv_table_set_column_width(objects.statistics_table, 5, 36); + lv_table_set_column_width(objects.statistics_table, 6, 36); + // fill table heading + lv_table_set_cell_value(objects.statistics_table, 0, 0, "Name"); + lv_table_set_cell_value(objects.statistics_table, 0, 1, "Tel"); + lv_table_set_cell_value(objects.statistics_table, 0, 2, "Pos"); + lv_table_set_cell_value(objects.statistics_table, 0, 3, "Inf"); + lv_table_set_cell_value(objects.statistics_table, 0, 4, "Trc"); + lv_table_set_cell_value(objects.statistics_table, 0, 5, "Nbr"); + lv_table_set_cell_value(objects.statistics_table, 0, 6, "All"); } void TFTView_320x240::updateTheme(void) @@ -435,7 +457,7 @@ void TFTView_320x240::ui_events_init(void) lv_obj_add_event_cb(objects.tools_signal_scanner_button, ui_event_signal_scanner, LV_EVENT_CLICKED, 0); lv_obj_add_event_cb(objects.tools_trace_route_button, ui_event_trace_route, LV_EVENT_CLICKED, 0); lv_obj_add_event_cb(objects.tools_neighbors_button, ui_event_neighbors, LV_EVENT_CLICKED, 0); - // lv_obj_add_event_cb(objects.tools_statistics_button, ui_event_statistics, LV_EVENT_CLICKED, 0); + lv_obj_add_event_cb(objects.tools_statistics_button, ui_event_statistics, LV_EVENT_ALL, 0); lv_obj_add_event_cb(objects.tools_packet_log_button, ui_event_packet_log, LV_EVENT_ALL, 0); // tools lv_obj_add_event_cb(objects.detector_start_button, ui_event_mesh_detector_start, LV_EVENT_CLICKED, 0); @@ -1490,7 +1512,13 @@ void TFTView_320x240::ui_event_neighbors(lv_event_t *e) void TFTView_320x240::ui_event_statistics(lv_event_t *e) { - THIS->ui_set_active(objects.settings_button, objects.tools_statistics_panel, objects.top_statistics_label); + lv_event_code_t event_code = lv_event_get_code(e); + if (event_code == LV_EVENT_CLICKED) { + THIS->ui_set_active(objects.settings_button, objects.tools_statistics_panel, objects.top_statistics_panel); + } else if (event_code == LV_EVENT_LONG_PRESSED) { + // clear statistics table + THIS->updateStatistics(meshtastic_MeshPacket{.from = 0}); + } } void TFTView_320x240::ui_event_packet_log(lv_event_t *e) @@ -1555,7 +1583,7 @@ void TFTView_320x240::writePacketLog(const meshtastic_MeshPacket &p) {5, "routing"}, {6, "admin"}, {7, "text message"}, {8, "waypoint"}, {9, "audio"}, {10, "sensor"}, {32, "reply"}, {33, "ip tunnel"}, {34, "paxcounter"}, {64, "serial"}, {65, "store forward"}, {66, "range test"}, {67, "telemetry"}, {68, "ZPS"}, {69, "simulator"}, - {70, "trace route"}, {71, "neighbor info"}, {72, "atax"}, {73, "map report"}, {74, "power stress"}, + {70, "tracert"}, {71, "neighbor info"}, {72, "atax"}, {73, "map report"}, {74, "power stress"}, {256, "private"}, {257, "atax forwarder"}}; // ignore admin packages initiated by us @@ -1673,6 +1701,167 @@ void TFTView_320x240::writePacketLog(const meshtastic_MeshPacket &p) lv_obj_scroll_to_view(pLabel, LV_ANIM_OFF); } +void TFTView_320x240::updateStatistics(const meshtastic_MeshPacket &p) +{ + struct Stats { + uint32_t id; + uint16_t row; + uint16_t tel; + uint16_t pos; + uint16_t inf; + uint16_t trc; + uint16_t txt; + uint16_t nbr; + uint32_t sum; + + bool operator==(const Stats& rhs) const { + return id == rhs.id; + } + + Stats& operator+=(const Stats& rhs) { + this->tel += rhs.tel; + this->pos += rhs.pos; + this->inf += rhs.inf; + this->trc += rhs.trc; + this->txt += rhs.txt; + this->nbr += rhs.nbr; + this->sum += 1; + return *this; + } + + bool operator<(const Stats& rhs) const { + return sum > rhs.sum; // sort reverse but skip equal values + } + }; + static std::list stats; + + if (p.from == 0) { + // clear table + stats.clear(); + for (int i=1; i<=11; i++) { + for (int j=0; j<7; j++) { + lv_table_set_cell_value(objects.statistics_table, i, j, ""); + } + } + return; + } + + // update statistic for node + Stats stat = { p.from }; + switch (p.decoded.portnum) { + case meshtastic_PortNum_TELEMETRY_APP: { + meshtastic_Telemetry telemetry; + if (pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &meshtastic_Telemetry_msg, &telemetry)) { + if (telemetry.which_variant == meshtastic_Telemetry_device_metrics_tag) { + if (p.from == ownNode) + return; // suppress (internal) battery level packets + } + } + stat.tel++; + break; + } + case meshtastic_PortNum_POSITION_APP: { + stat.pos++; + break; + } + case meshtastic_PortNum_NODEINFO_APP: { + stat.inf++; + break; + } + case meshtastic_PortNum_TRACEROUTE_APP: { + stat.trc++; + break; + } + case meshtastic_PortNum_TEXT_MESSAGE_APP: { + stat.txt++; + break; + } + case meshtastic_PortNum_NEIGHBORINFO_APP: { + stat.nbr++; + break; + } + default: + ILOG_DEBUG("unspecified packet in stats\n"); + stat.sum++; + return; + } + + std::list::iterator it = std::find(stats.begin(), stats.end(), stat); + if (it == stats.end()) { + stat.row = stats.size(); + stat.sum = 1; + //TODO: stop if memory limit is reached + stats.push_back(stat); + } + else { + *it += stat; + } + + stats.sort(); + + // fill packet statistics table + char buf[10]; + int row = 1; + bool move = false; + for (auto it2 : stats) { + if (it2.id == p.from || move) { + char *userData = (char *)&(nodes[it2.id]->LV_OBJ_IDX(node_lbs_idx)->user_data); + buf[0] = userData[0]; + buf[1] = userData[1]; + buf[2] = userData[2]; + buf[3] = userData[3]; + buf[4] = '\0'; + + // if name is empty or using glyphs then replace with short id + uint32_t width = lv_txt_get_width(buf, strlen(buf), &ui_font_montserrat_12, 0); + if (!width) { + sprintf(buf, "%04x", it2.id & 0xffff); + } + + lv_table_set_cell_value(objects.statistics_table, row, 0, buf); + sprintf(buf, "%d", it2.tel); + lv_table_set_cell_value(objects.statistics_table, row, 1, buf); + sprintf(buf, "%d", it2.pos); + lv_table_set_cell_value(objects.statistics_table, row, 2, buf); + sprintf(buf, "%d", it2.inf); + lv_table_set_cell_value(objects.statistics_table, row, 3, buf); + sprintf(buf, "%d", it2.trc); + lv_table_set_cell_value(objects.statistics_table, row, 4, buf); + sprintf(buf, "%d", it2.nbr); + lv_table_set_cell_value(objects.statistics_table, row, 5, buf); + sprintf(buf, "%d", it2.sum); + lv_table_set_cell_value(objects.statistics_table, row, 6, buf); + move = true; + } + row++; + if (row > 11) // fill rows till bottom of 320x240 display + break; + } +} + +void TFTView_320x240::ui_event_statistics_table(lv_event_t *e) +{ + lv_draw_task_t * draw_task = lv_event_get_draw_task(e); + lv_draw_dsc_base_t * base_dsc = (lv_draw_dsc_base_t *)lv_draw_task_get_draw_dsc(draw_task); + // if the cells are drawn... + if(base_dsc->part == LV_PART_ITEMS) { + // make the texts in the first cell blueish + lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task); + if(fill_draw_dsc) { + uint32_t row = base_dsc->id1; + if(row == 0) { + fill_draw_dsc->color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), fill_draw_dsc->color, LV_OPA_20); + } + // make every 2nd row grayish + else { + Themes::recolorTableRow(fill_draw_dsc, row % 2 == 0); + } + } + } + +} + + /** * @brief User widget OK button handling * @@ -2753,7 +2942,7 @@ void TFTView_320x240::updateHopsAway(uint32_t nodeNum, uint8_t hopsAway) char buf[16]; sprintf(buf, "hops: %d", (int)hopsAway); lv_label_set_text(it->second->LV_OBJ_IDX(node_sig_idx), buf); - it->second->LV_OBJ_IDX(node_sig_idx)->user_data = (void *)hopsAway; + it->second->LV_OBJ_IDX(node_sig_idx)->user_data = (void *)(unsigned long)hopsAway; } } } @@ -3253,6 +3442,7 @@ void TFTView_320x240::packetReceived(const meshtastic_MeshPacket &p) if (packetLogEnabled) { writePacketLog(p); } + updateStatistics(p); } void TFTView_320x240::notifyResync(bool show) diff --git a/source/Themes.cpp b/source/Themes.cpp index 5c32199..0e2cecb 100644 --- a/source/Themes.cpp +++ b/source/Themes.cpp @@ -81,7 +81,14 @@ enum ThemeColor { eBatteryPercentageText, eColorTextLabel, eSpinnerMainArc, - eSpinnerIndicatorArc + eSpinnerIndicatorArc, + eTableHeadingText, + eTableHeadingBg, + eTableItemText, + eTableItemBg, + eTableItemDarkBg, + eTableBorder, + eTableCellBorder }; uint32_t themeColor[][2] = { @@ -143,10 +150,7 @@ uint32_t themeColor[][2] = { {0xffffffff, 0xffffffff}, // eTabButtonPressedText {0xffb0b0b0, 0xff505050}, // eTabButtonDefaultBorder {0xfffbfce9, 0xff303030}, // eChatMessageBg - { - 255, - 255, - }, // eChatMessageBgOpa + {255, 255}, // eChatMessageBgOpa {0xff294337, 0xffffffff}, // eChatMessageText {0xff888888, 0xff707070}, // eChatMessageBorder {0xffffffff, 0xff404040}, // eNewMessageBg @@ -162,6 +166,13 @@ uint32_t themeColor[][2] = { {0xff003c9f, 0xffaafbff}, // eColorTextLabel {0xffe0e0e0, 0xff404040}, // eSpinnerMainArc {0xff67ea94, 0xff67ea94}, // eSpinnerIndicatorArc + {0xff212121, 0xffaafbff}, // eTableHeadingText, + {0xfff4f4f0, 0xff303030}, // eTableHeadingBg + {0xff212121, 0xffaafbff}, // eTableItemText, + {0xfff4f4f0, 0xff505050}, // eTableItemBg + {0xffd4d4d0, 0xff303030}, // eTableItemDarkBg + {0xffe0e0e0, 0xff404040}, // eTableBorder + {0xffe0e0e0, 0xff404040} // eTableCellBorder }; #include "fonts.h" @@ -354,6 +365,17 @@ void apply_style_positive_image_style(void) lv_style_t *style = get_style_positive_image_style_MAIN_DEFAULT(); lv_style_set_image_recolor(style, lv_color_hex(THEME(ePositiveImageRecolor))); }; +void apply_style_statistics_table_style_MAIN_DEFAULT(void) { + lv_style_t *style = get_style_statistics_table_style_MAIN_DEFAULT(); + lv_style_set_border_color(style, lv_color_hex(THEME(eTableBorder))); +}; +void apply_style_statistics_table_style_ITEMS_DEFAULT(void) { + lv_style_t *style = get_style_statistics_table_style_ITEMS_DEFAULT(); + lv_style_set_bg_color(style, lv_color_hex(THEME(eTableItemBg))); + lv_style_set_text_color(style, lv_color_hex(THEME(eTableItemText))); + lv_style_set_border_color(style, lv_color_hex(THEME(eTableCellBorder))); +}; + } void Themes::set(enum Theme th) @@ -386,6 +408,8 @@ void Themes::set(enum Theme th) apply_style_spinner_style_INDICATOR_DEFAULT(); apply_style_settings_label_style(); apply_style_positive_image_style(); + apply_style_statistics_table_style_MAIN_DEFAULT(); + apply_style_statistics_table_style_ITEMS_DEFAULT(); } void Themes::initStyles(void) @@ -469,3 +493,13 @@ void Themes::recolorTopLabel(lv_obj_t *obj, bool alert) } lv_obj_set_style_text_color(obj, color, LV_PART_MAIN | LV_STATE_DEFAULT); } + +void Themes::recolorTableRow(lv_draw_fill_dsc_t* fill_draw_dsc, bool odd) +{ + if (odd) { + fill_draw_dsc->color = lv_color_hex(THEME(eTableItemBg)); + } + else { + fill_draw_dsc->color = lv_color_hex(THEME(eTableItemDarkBg)); + } +}