From 1796f63211abfde48164bfebfcc99d35d8288e6d Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 17 Jan 2021 05:50:06 +0800 Subject: [PATCH] use std::map for images (#19768) * use std::map for fonts&images * rebase master * use std::string * remove cmp_str * Update selfdrive/ui/paint.cc Co-authored-by: Adeeb Shihadeh --- selfdrive/ui/paint.cc | 124 ++++++++++++++++++++-------------------- selfdrive/ui/paint.hpp | 2 +- selfdrive/ui/sidebar.cc | 20 +++---- selfdrive/ui/ui.hpp | 14 +---- 4 files changed, 76 insertions(+), 84 deletions(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index c4d8414c95..88549a9eb7 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -56,11 +56,11 @@ bool car_space_to_full_frame(const UIState *s, float in_x, float in_y, float in_ } -static void ui_draw_text(NVGcontext *vg, float x, float y, const char* string, float size, NVGcolor color, int font){ - nvgFontFaceId(vg, font); - nvgFontSize(vg, size); - nvgFillColor(vg, color); - nvgText(vg, x, y, string, NULL); +static void ui_draw_text(const UIState *s, float x, float y, const char* string, float size, NVGcolor color, const char *font_name){ + nvgFontFace(s->vg, font_name); + nvgFontSize(s->vg, size); + nvgFillColor(s->vg, color); + nvgText(s->vg, x, y, string, NULL); } static void draw_chevron(UIState *s, float x_in, float y_in, float sz, @@ -94,19 +94,19 @@ static void draw_chevron(UIState *s, float x_in, float y_in, float sz, nvgFill(s->vg); } -static void ui_draw_circle_image(NVGcontext *vg, int x, int y, int size, int image, NVGcolor color, float img_alpha, int img_y = 0) { +static void ui_draw_circle_image(const UIState *s, int x, int y, int size, const char *image, NVGcolor color, float img_alpha, int img_y = 0) { const int img_size = size * 1.5; - nvgBeginPath(vg); - nvgCircle(vg, x, y + (bdr_s * 1.5), size); - nvgFillColor(vg, color); - nvgFill(vg); - ui_draw_image(vg, {x - (img_size / 2), img_y ? img_y : y - (size / 4), img_size, img_size}, image, img_alpha); + nvgBeginPath(s->vg); + nvgCircle(s->vg, x, y + (bdr_s * 1.5), size); + nvgFillColor(s->vg, color); + nvgFill(s->vg); + ui_draw_image(s, {x - (img_size / 2), img_y ? img_y : y - (size / 4), img_size, img_size}, image, img_alpha); } -static void ui_draw_circle_image(NVGcontext *vg, int x, int y, int size, int image, bool active) { +static void ui_draw_circle_image(const UIState *s, int x, int y, int size, const char *image, bool active) { float bg_alpha = active ? 0.3f : 0.1f; float img_alpha = active ? 1.0f : 0.15f; - ui_draw_circle_image(vg, x, y, size, image, nvgRGBA(0, 0, 0, (255 * bg_alpha)), img_alpha); + ui_draw_circle_image(s, x, y, size, image, nvgRGBA(0, 0, 0, (255 * bg_alpha)), img_alpha); } static void draw_lead(UIState *s, const cereal::RadarState::LeadData::Reader &lead){ @@ -225,12 +225,12 @@ static void ui_draw_vision_maxspeed(UIState *s) { ui_draw_rect(s->vg, rect, COLOR_WHITE_ALPHA(100), 10, 20.); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - ui_draw_text(s->vg, rect.centerX(), 148, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); + ui_draw_text(s, rect.centerX(), 148, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), "sans-regular"); if (is_cruise_set) { const std::string maxspeed_str = std::to_string((int)std::nearbyint(maxspeed)); - ui_draw_text(s->vg, rect.centerX(), 242, maxspeed_str.c_str(), 48 * 2.5, COLOR_WHITE, s->font_sans_bold); + ui_draw_text(s, rect.centerX(), 242, maxspeed_str.c_str(), 48 * 2.5, COLOR_WHITE, "sans-bold"); } else { - ui_draw_text(s->vg, rect.centerX(), 242, "N/A", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); + ui_draw_text(s, rect.centerX(), 242, "N/A", 42 * 2.5, COLOR_WHITE_ALPHA(100), "sans-semibold"); } } @@ -238,8 +238,8 @@ static void ui_draw_vision_speed(UIState *s) { const float speed = std::max(0.0, s->scene.controls_state.getVEgo() * (s->is_metric ? 3.6 : 2.2369363)); const std::string speed_str = std::to_string((int)std::nearbyint(speed)); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - ui_draw_text(s->vg, s->scene.viz_rect.centerX(), 240, speed_str.c_str(), 96 * 2.5, COLOR_WHITE, s->font_sans_bold); - ui_draw_text(s->vg, s->scene.viz_rect.centerX(), 320, s->is_metric ? "km/h" : "mph", 36 * 2.5, COLOR_WHITE_ALPHA(200), s->font_sans_regular); + ui_draw_text(s, s->scene.viz_rect.centerX(), 240, speed_str.c_str(), 96 * 2.5, COLOR_WHITE, "sans-bold"); + ui_draw_text(s, s->scene.viz_rect.centerX(), 320, s->is_metric ? "km/h" : "mph", 36 * 2.5, COLOR_WHITE_ALPHA(200), "sans-regular"); } static void ui_draw_vision_event(UIState *s) { @@ -250,7 +250,7 @@ static void ui_draw_vision_event(UIState *s) { // draw winding road sign const int img_turn_size = 160*1.5; const Rect rect = {viz_event_x - (img_turn_size / 4), viz_event_y + bdr_s - 25, img_turn_size, img_turn_size}; - ui_draw_image(s->vg, rect, s->img_turn, 1.0f); + ui_draw_image(s, rect, "trafficSign_turn", 1.0f); } else if (s->scene.controls_state.getEngageable()) { // draw steering wheel const int bg_wheel_size = 96; @@ -258,7 +258,7 @@ static void ui_draw_vision_event(UIState *s) { const int bg_wheel_y = viz_event_y + (bg_wheel_size/2); const NVGcolor color = bg_colors[s->status]; - ui_draw_circle_image(s->vg, bg_wheel_x, bg_wheel_y, bg_wheel_size, s->img_wheel, color, 1.0f, bg_wheel_y - 25); + ui_draw_circle_image(s, bg_wheel_x, bg_wheel_y, bg_wheel_size, "wheel", color, 1.0f, bg_wheel_y - 25); } } @@ -266,7 +266,7 @@ static void ui_draw_vision_face(UIState *s) { const int face_size = 96; const int face_x = (s->scene.viz_rect.x + face_size + (bdr_s * 2)); const int face_y = (s->scene.viz_rect.bottom() - footer_h + ((footer_h - face_size) / 2)); - ui_draw_circle_image(s->vg, face_x, face_y, face_size, s->img_face, s->scene.dmonitoring_state.getFaceDetected()); + ui_draw_circle_image(s, face_x, face_y, face_size, "driver_face", s->scene.dmonitoring_state.getFaceDetected()); } static void ui_draw_driver_view(UIState *s) { @@ -307,7 +307,7 @@ static void ui_draw_driver_view(UIState *s) { const int face_size = 85; const int icon_x = is_rhd ? rect.right() - face_size - bdr_s * 2 : rect.x + face_size + bdr_s * 2; const int icon_y = rect.bottom() - face_size - bdr_s * 2.5; - ui_draw_circle_image(s->vg, icon_x, icon_y, face_size, s->img_face, face_detected); + ui_draw_circle_image(s, icon_x, icon_y, face_size, "driver_face", face_detected); } static void ui_draw_vision_header(UIState *s) { @@ -356,17 +356,17 @@ static void ui_draw_vision_alert(UIState *s) { nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); if (scene->alert_size == cereal::ControlsState::AlertSize::SMALL) { - ui_draw_text(s->vg, rect.centerX(), rect.centerY() + 15, scene->alert_text1.c_str(), 40*2.5, COLOR_WHITE, s->font_sans_semibold); + ui_draw_text(s, rect.centerX(), rect.centerY() + 15, scene->alert_text1.c_str(), 40*2.5, COLOR_WHITE, "sans-semibold"); } else if (scene->alert_size == cereal::ControlsState::AlertSize::MID) { - ui_draw_text(s->vg, rect.centerX(), rect.centerY() - 45, scene->alert_text1.c_str(), 48*2.5, COLOR_WHITE, s->font_sans_bold); - ui_draw_text(s->vg, rect.centerX(), rect.centerY() + 75, scene->alert_text2.c_str(), 36*2.5, COLOR_WHITE, s->font_sans_regular); + ui_draw_text(s, rect.centerX(), rect.centerY() - 45, scene->alert_text1.c_str(), 48*2.5, COLOR_WHITE, "sans-bold"); + ui_draw_text(s, rect.centerX(), rect.centerY() + 75, scene->alert_text2.c_str(), 36*2.5, COLOR_WHITE, "sans-regular"); } else if (scene->alert_size == cereal::ControlsState::AlertSize::FULL) { nvgFontSize(s->vg, (longAlert1?72:96)*2.5); - nvgFontFaceId(s->vg, s->font_sans_bold); + nvgFontFace(s->vg, "sans-bold"); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); nvgTextBox(s->vg, rect.x, rect.y+(longAlert1?360:420), rect.w-60, scene->alert_text1.c_str(), NULL); nvgFontSize(s->vg, 48*2.5); - nvgFontFaceId(s->vg, s->font_sans_regular); + nvgFontFace(s->vg, "sans-regular"); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); nvgTextBox(s->vg, rect.x, rect.h-(longAlert1?300:360), rect.w-60, scene->alert_text2.c_str(), NULL); } @@ -443,12 +443,12 @@ void ui_draw(UIState *s) { glDisable(GL_BLEND); } -void ui_draw_image(NVGcontext *vg, const Rect &r, int image, float alpha){ - nvgBeginPath(vg); - NVGpaint imgPaint = nvgImagePattern(vg, r.x, r.y, r.w, r.h, 0, image, alpha); - nvgRect(vg, r.x, r.y, r.w, r.h); - nvgFillPaint(vg, imgPaint); - nvgFill(vg); +void ui_draw_image(const UIState *s, const Rect &r, const char *name, float alpha){ + nvgBeginPath(s->vg); + NVGpaint imgPaint = nvgImagePattern(s->vg, r.x, r.y, r.w, r.h, 0, s->images.at(name), alpha); + nvgRect(s->vg, r.x, r.y, r.w, r.h); + nvgFillPaint(s->vg, imgPaint); + nvgFill(s->vg); } void ui_draw_rect(NVGcontext *vg, const Rect &r, NVGcolor color, int width, float radius) { @@ -525,36 +525,38 @@ void ui_nvg_init(UIState *s) { #else s->vg = nvgCreate(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG); #endif - assert(s->vg); - s->font_sans_regular = nvgCreateFont(s->vg, "sans-regular", "../assets/fonts/opensans_regular.ttf"); - assert(s->font_sans_regular >= 0); - s->font_sans_semibold = nvgCreateFont(s->vg, "sans-semibold", "../assets/fonts/opensans_semibold.ttf"); - assert(s->font_sans_semibold >= 0); - s->font_sans_bold = nvgCreateFont(s->vg, "sans-bold", "../assets/fonts/opensans_bold.ttf"); - assert(s->font_sans_bold >= 0); - - s->img_wheel = nvgCreateImage(s->vg, "../assets/img_chffr_wheel.png", 1); - assert(s->img_wheel != 0); - s->img_turn = nvgCreateImage(s->vg, "../assets/img_trafficSign_turn.png", 1); - assert(s->img_turn != 0); - s->img_face = nvgCreateImage(s->vg, "../assets/img_driver_face.png", 1); - assert(s->img_face != 0); - s->img_button_settings = nvgCreateImage(s->vg, "../assets/images/button_settings.png", 1); - assert(s->img_button_settings != 0); - s->img_button_home = nvgCreateImage(s->vg, "../assets/images/button_home.png", 1); - assert(s->img_button_home != 0); - s->img_battery = nvgCreateImage(s->vg, "../assets/images/battery.png", 1); - assert(s->img_battery != 0); - s->img_battery_charging = nvgCreateImage(s->vg, "../assets/images/battery_charging.png", 1); - assert(s->img_battery_charging != 0); - - for(int i=0;i<=5;++i) { - char network_asset[32]; - snprintf(network_asset, sizeof(network_asset), "../assets/images/network_%d.png", i); - s->img_network[i] = nvgCreateImage(s->vg, network_asset, 1); - assert(s->img_network[i] != 0); + // init fonts + std::pair fonts[] = { + {"sans-regular", "../assets/fonts/opensans_regular.ttf"}, + {"sans-semibold", "../assets/fonts/opensans_semibold.ttf"}, + {"sans-bold", "../assets/fonts/opensans_bold.ttf"}, + }; + for (auto [name, file] : fonts) { + int font_id = nvgCreateFont(s->vg, name, file); + assert(font_id >= 0); + } + + // init images + std::vector> images = { + {"wheel", "../assets/img_chffr_wheel.png"}, + {"trafficSign_turn", "../assets/img_trafficSign_turn.png"}, + {"driver_face", "../assets/img_driver_face.png"}, + {"button_settings", "../assets/images/button_settings.png"}, + {"button_home", "../assets/images/button_home.png"}, + {"battery", "../assets/images/battery.png"}, + {"battery_charging", "../assets/images/battery_charging.png"}, + {"network_0", "../assets/images/network_0.png"}, + {"network_1", "../assets/images/network_1.png"}, + {"network_2", "../assets/images/network_2.png"}, + {"network_3", "../assets/images/network_3.png"}, + {"network_4", "../assets/images/network_4.png"}, + {"network_5", "../assets/images/network_5.png"}, + }; + for (auto [name, file] : images) { + s->images[name] = nvgCreateImage(s->vg, file, 1); + assert(s->images[name] != 0); } // init gl diff --git a/selfdrive/ui/paint.hpp b/selfdrive/ui/paint.hpp index 62a8c6a05b..7bab393a34 100644 --- a/selfdrive/ui/paint.hpp +++ b/selfdrive/ui/paint.hpp @@ -3,7 +3,7 @@ bool car_space_to_full_frame(const UIState *s, float in_x, float in_y, float in_z, vertex_data *out, float margin=0.0); void ui_draw(UIState *s); -void ui_draw_image(NVGcontext *vg, const Rect &r, int image, float alpha); +void ui_draw_image(const UIState *s, const Rect &r, const char *name, float alpha); void ui_draw_rect(NVGcontext *vg, const Rect &r, NVGcolor color, int width, float radius = 0); void ui_fill_rect(NVGcontext *vg, const Rect &r, const NVGpaint &paint, float radius = 0); void ui_fill_rect(NVGcontext *vg, const Rect &r, const NVGcolor &color, float radius = 0); diff --git a/selfdrive/ui/sidebar.cc b/selfdrive/ui/sidebar.cc index 2ba9020f9e..a5fbced5cc 100644 --- a/selfdrive/ui/sidebar.cc +++ b/selfdrive/ui/sidebar.cc @@ -2,7 +2,7 @@ #include #include #include - +#include "common/util.h" #include "paint.hpp" #include "sidebar.hpp" @@ -17,12 +17,12 @@ static void draw_background(UIState *s) { static void draw_settings_button(UIState *s) { const float alpha = s->active_app == cereal::UiLayoutState::App::SETTINGS ? 1.0f : 0.65f; - ui_draw_image(s->vg, settings_btn, s->img_button_settings, alpha); + ui_draw_image(s, settings_btn, "button_settings", alpha); } static void draw_home_button(UIState *s) { const float alpha = s->active_app == cereal::UiLayoutState::App::HOME ? 1.0f : 0.65f; - ui_draw_image(s->vg, home_btn, s->img_button_home, alpha); + ui_draw_image(s, home_btn, "button_home", alpha); } static void draw_network_strength(UIState *s) { @@ -33,15 +33,15 @@ static void draw_network_strength(UIState *s) { {cereal::ThermalData::NetworkStrength::GOOD, 4}, {cereal::ThermalData::NetworkStrength::GREAT, 5}}; const int img_idx = s->scene.thermal.getNetworkType() == cereal::ThermalData::NetworkType::NONE ? 0 : network_strength_map[s->scene.thermal.getNetworkStrength()]; - ui_draw_image(s->vg, {58, 196, 176, 27}, s->img_network[img_idx], 1.0f); + ui_draw_image(s, {58, 196, 176, 27}, util::string_format("network_%d", img_idx).c_str(), 1.0f); } static void draw_battery_icon(UIState *s) { - int battery_img = s->scene.thermal.getBatteryStatus() == "Charging" ? s->img_battery_charging : s->img_battery; + const char *battery_img = s->scene.thermal.getBatteryStatus() == "Charging" ? "battery_charging" : "battery"; const Rect rect = {160, 255, 76, 36}; ui_fill_rect(s->vg, {rect.x + 6, rect.y + 5, int((rect.w - 19) * s->scene.thermal.getBatteryPercent() * 0.01), rect.h - 11}, COLOR_WHITE); - ui_draw_image(s->vg, rect, battery_img, 1.0f); + ui_draw_image(s, rect, battery_img, 1.0f); } static void draw_network_type(UIState *s) { @@ -58,7 +58,7 @@ static void draw_network_type(UIState *s) { const char *network_type = network_type_map[s->scene.thermal.getNetworkType()]; nvgFillColor(s->vg, COLOR_WHITE); nvgFontSize(s->vg, 48); - nvgFontFaceId(s->vg, s->font_sans_regular); + nvgFontFace(s->vg, "sans-regular"); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); nvgTextBox(s->vg, network_x, network_y, network_w, network_type ? network_type : "--", NULL); } @@ -85,19 +85,19 @@ static void draw_metric(UIState *s, const char *label_str, const char *value_str if (!message_str) { nvgFillColor(s->vg, COLOR_WHITE); nvgFontSize(s->vg, 78); - nvgFontFaceId(s->vg, s->font_sans_bold); + nvgFontFace(s->vg, "sans-bold"); nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); nvgTextBox(s->vg, rect.x + 50, rect.y + 50, rect.w - 60, value_str, NULL); nvgFillColor(s->vg, COLOR_WHITE); nvgFontSize(s->vg, 48); - nvgFontFaceId(s->vg, s->font_sans_regular); + nvgFontFace(s->vg, "sans-regular"); nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); nvgTextBox(s->vg, rect.x + 50, rect.y + 50 + 66, rect.w - 60, label_str, NULL); } else { nvgFillColor(s->vg, COLOR_WHITE); nvgFontSize(s->vg, 48); - nvgFontFaceId(s->vg, s->font_sans_bold); + nvgFontFace(s->vg, "sans-bold"); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); nvgTextBox(s->vg, rect.x + 35, rect.y + (strchr(message_str, '\n') ? 40 : 50), rect.w - 50, message_str, NULL); } diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index 3a5b749311..1363cddf72 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -151,18 +151,8 @@ typedef struct UIState { // NVG NVGcontext *vg; - // fonts and images - int font_sans_regular; - int font_sans_semibold; - int font_sans_bold; - int img_wheel; - int img_turn; - int img_face; - int img_button_settings; - int img_button_home; - int img_battery; - int img_battery_charging; - int img_network[6]; + // images + std::map images; SubMaster *sm;