UI: simplify layout calculation (#2131)

* add Rect struct

* simplify layout calculation by using viz_rect

* fix

* add whitespace

* use the correct value for vwp_w

* correct vwp_w again

* rebase

* dd
albatross
Dean Lee 2020-09-13 09:35:36 +08:00 committed by GitHub
parent 1fd13c87b4
commit 8417be6f40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 82 additions and 98 deletions

View File

@ -116,7 +116,7 @@ static void set_awake(UIState *s, bool awake) {
}
static void handle_vision_touch(UIState *s, int touch_x, int touch_y) {
if (s->started && (touch_x >= s->scene.ui_viz_rx - bdr_s)
if (s->started && (touch_x >= s->scene.viz_rect.x - bdr_s)
&& (s->active_app != cereal::UiLayoutState::App::SETTINGS)) {
if (!s->scene.frontview) {
s->scene.uilayout_sidebarcollapsed = !s->scene.uilayout_sidebarcollapsed;
@ -128,11 +128,9 @@ static void handle_vision_touch(UIState *s, int touch_x, int touch_y) {
static void handle_sidebar_touch(UIState *s, int touch_x, int touch_y) {
if (!s->scene.uilayout_sidebarcollapsed && touch_x <= sbr_w) {
if (touch_x >= settings_btn_x && touch_x < (settings_btn_x + settings_btn_w)
&& touch_y >= settings_btn_y && touch_y < (settings_btn_y + settings_btn_h)) {
if (settings_btn.ptInRect(touch_x, touch_y)) {
s->active_app = cereal::UiLayoutState::App::SETTINGS;
} else if (touch_x >= home_btn_x && touch_x < (home_btn_x + home_btn_w)
&& touch_y >= home_btn_y && touch_y < (home_btn_y + home_btn_h)) {
} else if (home_btn.ptInRect(touch_x, touch_y)) {
if (s->started) {
s->active_app = cereal::UiLayoutState::App::NONE;
s->scene.uilayout_sidebarcollapsed = true;

View File

@ -225,11 +225,11 @@ static void ui_draw_track(UIState *s, bool is_mpc, track_vertices_data *pvd) {
if (is_mpc) {
// Draw colored MPC track
const Color clr = bg_colors[s->status];
track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4,
track_bg = nvgLinearGradient(s->vg, s->fb_w, s->fb_h, s->fb_w, s->fb_h*.4,
nvgRGBA(clr.r, clr.g, clr.b, 255), nvgRGBA(clr.r, clr.g, clr.b, 255/2));
} else {
// Draw white vision track
track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4,
track_bg = nvgLinearGradient(s->vg, s->fb_w, s->fb_h, s->fb_w, s->fb_h*.4,
COLOR_WHITE, COLOR_WHITE_ALPHA(0));
}
nvgFillPaint(s->vg, track_bg);
@ -338,23 +338,17 @@ static void ui_draw_vision_lanes(UIState *s) {
// Draw all world space objects.
static void ui_draw_world(UIState *s) {
const UIScene *scene = &s->scene;
if (!scene->world_objects_visible) {
return;
}
const int inner_height = float(viz_w) * vwp_h / vwp_w;
const int ui_viz_rx = scene->ui_viz_rx;
const int ui_viz_rw = scene->ui_viz_rw;
const int ui_viz_ro = scene->ui_viz_ro;
const Rect &viz_rect = scene->viz_rect;
const int viz_w = s->fb_w - bdr_s * 2;
const int inner_height = float(viz_w) * s->fb_h / s->fb_w;
nvgSave(s->vg);
nvgScissor(s->vg, ui_viz_rx, box_y, ui_viz_rw, box_h);
nvgScissor(s->vg, viz_rect.x, viz_rect.y, viz_rect.w, viz_rect.h);
nvgTranslate(s->vg, ui_viz_rx+ui_viz_ro, box_y + (box_h-inner_height)/2.0);
nvgTranslate(s->vg, viz_rect.x+scene->ui_viz_ro, viz_rect.y + (viz_rect.h-inner_height)/2.0);
nvgScale(s->vg, (float)viz_w / s->fb_w, (float)inner_height / s->fb_h);
float w = 1440.0f; // Why 1440?
nvgTranslate(s->vg, (vwp_w - w) / 2.0f, 0.0);
nvgTranslate(s->vg, (s->fb_w - w) / 2.0f, 0.0);
nvgTranslate(s->vg, -w / 2, -1080.0f / 2);
nvgScale(s->vg, 2.0, 2.0);
@ -387,8 +381,8 @@ static void ui_draw_vision_maxspeed(UIState *s) {
int viz_maxspeed_w = 184;
int viz_maxspeed_h = 202;
int viz_maxspeed_x = (s->scene.ui_viz_rx + (bdr_s*2));
int viz_maxspeed_y = (box_y + (bdr_s*1.5));
int viz_maxspeed_x = s->scene.viz_rect.x + (bdr_s*2);
int viz_maxspeed_y = s->scene.viz_rect.y + (bdr_s*1.5);
int viz_maxspeed_xo = 180;
viz_maxspeed_xo = 0;
@ -413,29 +407,29 @@ static void ui_draw_vision_maxspeed(UIState *s) {
}
static void ui_draw_vision_speed(UIState *s) {
const UIScene *scene = &s->scene;
const Rect &viz_rect = s->scene.viz_rect;
float v_ego = s->scene.controls_state.getVEgo();
float speed = v_ego * 2.2369363 + 0.5;
if (s->is_metric){
speed = v_ego * 3.6 + 0.5;
}
const int viz_speed_w = 280;
const int viz_speed_x = scene->ui_viz_rx+((scene->ui_viz_rw/2)-(viz_speed_w/2));
const int viz_speed_x = viz_rect.centerX() - viz_speed_w/2;
char speed_str[32];
nvgBeginPath(s->vg);
nvgRect(s->vg, viz_speed_x, box_y, viz_speed_w, header_h);
nvgRect(s->vg, viz_speed_x, viz_rect.y, viz_speed_w, header_h);
nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE);
snprintf(speed_str, sizeof(speed_str), "%d", (int)speed);
ui_draw_text(s->vg, viz_speed_x + viz_speed_w / 2, 240, speed_str, 96*2.5, COLOR_WHITE, s->font_sans_bold);
ui_draw_text(s->vg, viz_speed_x + viz_speed_w / 2, 320, s->is_metric?"km/h":"mph", 36*2.5, COLOR_WHITE_ALPHA(200), s->font_sans_regular);
ui_draw_text(s->vg, viz_rect.centerX(), 240, speed_str, 96*2.5, COLOR_WHITE, s->font_sans_bold);
ui_draw_text(s->vg, viz_rect.centerX(), 320, s->is_metric?"km/h":"mph", 36*2.5, COLOR_WHITE_ALPHA(200), s->font_sans_regular);
}
static void ui_draw_vision_event(UIState *s) {
const int viz_event_w = 220;
const int viz_event_x = ((s->scene.ui_viz_rx + s->scene.ui_viz_rw) - (viz_event_w + (bdr_s*2)));
const int viz_event_y = (box_y + (bdr_s*1.5));
const int viz_event_x = s->scene.viz_rect.right() - (viz_event_w + bdr_s*2);
const int viz_event_y = s->scene.viz_rect.y + (bdr_s*1.5);
if (s->scene.controls_state.getDecelForModel() && s->scene.controls_state.getEnabled()) {
// draw winding road sign
const int img_turn_size = 160*1.5;
@ -462,17 +456,21 @@ static void ui_draw_vision_event(UIState *s) {
static void ui_draw_vision_face(UIState *s) {
const int face_size = 96;
const int face_x = (s->scene.ui_viz_rx + face_size + (bdr_s * 2));
const int face_y = (footer_y + ((footer_h - face_size) / 2));
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());
}
static void ui_draw_driver_view(UIState *s) {
const UIScene *scene = &s->scene;
s->scene.uilayout_sidebarcollapsed = true;
const int frame_x = scene->ui_viz_rx;
const int frame_w = scene->ui_viz_rw;
const int valid_frame_w = 4 * box_h / 3;
const Rect &viz_rect = s->scene.viz_rect;
const int ff_xoffset = 32;
const int frame_x = viz_rect.x;
const int frame_w = viz_rect.w;
const int valid_frame_w = 4 * viz_rect.h / 3;
const int box_y = viz_rect.y;
const int box_h = viz_rect.h;
const int valid_frame_x = frame_x + (frame_w - valid_frame_w) / 2 + ff_xoffset;
// blackout
@ -517,16 +515,13 @@ static void ui_draw_driver_view(UIState *s) {
}
static void ui_draw_vision_header(UIState *s) {
const UIScene *scene = &s->scene;
int ui_viz_rx = scene->ui_viz_rx;
int ui_viz_rw = scene->ui_viz_rw;
NVGpaint gradient = nvgLinearGradient(s->vg, ui_viz_rx,
(box_y+(header_h-(header_h/2.5))),
ui_viz_rx, box_y+header_h,
const Rect &viz_rect = s->scene.viz_rect;
NVGpaint gradient = nvgLinearGradient(s->vg, viz_rect.x,
viz_rect.y+(header_h-(header_h/2.5)),
viz_rect.x, viz_rect.y+header_h,
nvgRGBAf(0,0,0,0.45), nvgRGBAf(0,0,0,0));
ui_draw_rect(s->vg, ui_viz_rx, box_y, ui_viz_rw, header_h, gradient);
ui_draw_rect(s->vg, viz_rect.x, viz_rect.y, viz_rect.w, header_h, gradient);
ui_draw_vision_maxspeed(s);
ui_draw_vision_speed(s);
@ -543,7 +538,7 @@ void ui_draw_vision_alert(UIState *s, cereal::ControlsState::AlertSize va_size,
{cereal::ControlsState::AlertSize::NONE, 0},
{cereal::ControlsState::AlertSize::SMALL, 241},
{cereal::ControlsState::AlertSize::MID, 390},
{cereal::ControlsState::AlertSize::FULL, vwp_h}};
{cereal::ControlsState::AlertSize::FULL, s->fb_h}};
const UIScene *scene = &s->scene;
bool longAlert1 = strlen(va_text1) > 15;
@ -551,10 +546,10 @@ void ui_draw_vision_alert(UIState *s, cereal::ControlsState::AlertSize va_size,
const uint8_t *color = alert_colors[va_color];
int alr_s = alert_size_map[va_size];
const int alr_x = scene->ui_viz_rx - bdr_s;
const int alr_w = scene->ui_viz_rw + (bdr_s*2);
const int alr_x = scene->viz_rect.x - bdr_s;
const int alr_w = scene->viz_rect.w + (bdr_s*2);
const int alr_h = alr_s+(va_size==cereal::ControlsState::AlertSize::NONE?0:bdr_s);
const int alr_y = vwp_h-alr_h;
const int alr_y = s->fb_h-alr_h;
ui_draw_rect(s->vg, alr_x, alr_y, alr_w, alr_h, nvgRGBA(color[0],color[1],color[2],(color[3]*s->alert_blinking_alpha)));
@ -584,21 +579,20 @@ void ui_draw_vision_alert(UIState *s, cereal::ControlsState::AlertSize va_size,
static void ui_draw_vision(UIState *s) {
const UIScene *scene = &s->scene;
const Rect &viz_rect = scene->viz_rect;
// Draw video frames
glEnable(GL_SCISSOR_TEST);
glViewport(scene->ui_viz_rx+scene->ui_viz_ro, s->fb_h-(box_y+box_h), viz_w, box_h);
glScissor(scene->ui_viz_rx, s->fb_h-(box_y+box_h), scene->ui_viz_rw, box_h);
glViewport(viz_rect.x+scene->ui_viz_ro, viz_rect.y, s->fb_w - bdr_s*2, viz_rect.h);
glScissor(viz_rect.x, viz_rect.y, viz_rect.w, viz_rect.h);
draw_frame(s);
glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, s->fb_w, s->fb_h);
// Draw augmented elements
if (!scene->frontview) {
if (!scene->frontview && scene->world_objects_visible) {
ui_draw_world(s);
}
// Set Speed, Current Speed, Status/Events
if (!scene->frontview) {
ui_draw_vision_header(s);
@ -621,10 +615,13 @@ static void ui_draw_background(UIState *s) {
}
void ui_draw(UIState *s) {
const bool hasSidebar = !s->scene.uilayout_sidebarcollapsed;
s->scene.ui_viz_rx = hasSidebar ? box_x : (box_x - sbr_w + (bdr_s * 2));
s->scene.ui_viz_rw = hasSidebar ? box_w : (box_w + sbr_w - (bdr_s * 2));
s->scene.ui_viz_ro = hasSidebar ? - (sbr_w - 6 * bdr_s) : 0;
s->scene.viz_rect = Rect{bdr_s * 3, bdr_s, s->fb_w - 4 * bdr_s, s->fb_h - 2 * bdr_s};
s->scene.ui_viz_ro = 0;
if (!s->scene.uilayout_sidebarcollapsed) {
s->scene.viz_rect.x = sbr_w + bdr_s;
s->scene.viz_rect.w = s->fb_w - s->scene.viz_rect.x - bdr_s;
s->scene.ui_viz_ro = -(sbr_w - 6 * bdr_s);
}
ui_draw_background(s);
glEnable(GL_BLEND);
@ -704,14 +701,6 @@ static const mat4 device_transform = {{
0.0, 0.0, 0.0, 1.0,
}};
// frame from 4/3 to box size with a 2x zoom
static const mat4 frame_transform = {{
2*(4./3.)/((float)viz_w/box_h), 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
// frame from 4/3 to 16/9 display
static const mat4 full_to_wide_frame_transform = {{
.75, 0.0, 0.0, 0.0,
@ -816,6 +805,14 @@ void ui_nvg_init(UIState *s) {
glBindVertexArray(0);
}
// frame from 4/3 to box size with a 2x zoom
const mat4 frame_transform = {{
(float)(2*(4./3.)/((float)(s->fb_w-(bdr_s*2))/(s->fb_h-(bdr_s*2)))), 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
s->front_frame_mat = matmul(device_transform, full_to_wide_frame_transform);
s->rear_frame_mat = matmul(device_transform, frame_transform);

View File

@ -90,15 +90,12 @@ void GLWindow::paintGL() {
void GLWindow::mousePressEvent(QMouseEvent *e) {
// Settings button click
if (!ui_state->scene.uilayout_sidebarcollapsed && e->x() <= sbr_w) {
if (e->x() >= settings_btn_x && e->x() < (settings_btn_x + settings_btn_w)
&& e->y() >= settings_btn_y && e->y() < (settings_btn_y + settings_btn_h)) {
emit openSettings();
}
if (!ui_state->scene.uilayout_sidebarcollapsed && settings_btn.ptInRect(e->x(), e->y())) {
emit openSettings();
}
// Vision click
if (ui_state->started && (e->x() >= ui_state->scene.ui_viz_rx - bdr_s)){
if (ui_state->started && (e->x() >= ui_state->scene.viz_rect.x - bdr_s)){
ui_state->scene.uilayout_sidebarcollapsed = !ui_state->scene.uilayout_sidebarcollapsed;
}
}

View File

@ -26,7 +26,12 @@ public slots:
};
#ifdef QCOM2
const int vwp_w = 2160;
#else
const int vwp_w = 1920;
#endif
const int vwp_h = 1080;
class GLWindow : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT

View File

@ -8,17 +8,17 @@
static void ui_draw_sidebar_background(UIState *s) {
int sbr_x = !s->scene.uilayout_sidebarcollapsed ? 0 : -(sbr_w) + bdr_s * 2;
ui_draw_rect(s->vg, sbr_x, 0, sbr_w, vwp_h, COLOR_BLACK_ALPHA(85));
ui_draw_rect(s->vg, sbr_x, 0, sbr_w, s->fb_h, COLOR_BLACK_ALPHA(85));
}
static void ui_draw_sidebar_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_x, settings_btn_y, settings_btn_w, settings_btn_h, s->img_button_settings, alpha);
ui_draw_image(s->vg, settings_btn.x, settings_btn.y, settings_btn.w, settings_btn.h, s->img_button_settings, alpha);
}
static void ui_draw_sidebar_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_x, home_btn_y, home_btn_w, home_btn_h, s->img_button_home, alpha);
ui_draw_image(s->vg, home_btn.x, home_btn.y, home_btn.w, home_btn.h, s->img_button_home, alpha);
}
static void ui_draw_sidebar_network_strength(UIState *s) {

View File

@ -37,36 +37,22 @@
#define UI_BUF_COUNT 4
// TODO: Detect dynamically
#ifdef QCOM2
const int vwp_w = 2160;
#else
const int vwp_w = 1920;
#endif
typedef struct Rect {
int x, y, w, h;
int centerX() const { return x + w / 2; }
int right() const { return x + w; }
int bottom() const { return y + h; }
bool ptInRect(int px, int py) const {
return px >= x && px < (x + w) && py >= y && py < (y + h);
}
} Rect;
const int vwp_h = 1080;
const int nav_w = 640;
const int nav_ww= 760;
const int sbr_w = 300;
const int bdr_s = 30;
const int box_x = sbr_w+bdr_s;
const int box_y = bdr_s;
const int box_w = vwp_w-sbr_w-(bdr_s*2);
const int box_h = vwp_h-(bdr_s*2);
const int viz_w = vwp_w-(bdr_s*2);
const int ff_xoffset = 32;
const int header_h = 420;
const int footer_h = 280;
const int footer_y = vwp_h-bdr_s-footer_h;
const int settings_btn_h = 117;
const int settings_btn_w = 200;
const int settings_btn_x = 50;
const int settings_btn_y = 35;
const int home_btn_h = 180;
const int home_btn_w = 180;
const int home_btn_x = 60;
const int home_btn_y = vwp_h - home_btn_h - 40;
const Rect settings_btn = {50, 35, 200, 117};
const Rect home_btn = {60, 1080 - 180 - 40, 180, 180};
const int UI_FREQ = 20; // Hz
@ -114,7 +100,8 @@ typedef struct UIScene {
bool frontview;
bool uilayout_sidebarcollapsed;
// responsive layout
int ui_viz_rx, ui_viz_rw, ui_viz_ro;
Rect viz_rect;
int ui_viz_ro;
std::string alert_text1;
std::string alert_text2;