Qt offroad home screen (#2672)
* some cleanup first * home sweet home * basic home screen * date * fix touch * fix mac * hide when onroad * box layout didn't do what i thoughtpull/2683/head
parent
05fe01e30b
commit
fed642c4ed
9 changed files with 341 additions and 261 deletions
@ -0,0 +1,220 @@ |
||||
#include <cmath> |
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <thread> |
||||
|
||||
#include <QLabel> |
||||
#include <QMouseEvent> |
||||
#include <QHBoxLayout> |
||||
#include <QVBoxLayout> |
||||
#include <QDateTime> |
||||
|
||||
#include "common/params.h" |
||||
|
||||
#include "home.hpp" |
||||
#include "paint.hpp" |
||||
#include "qt_window.hpp" |
||||
|
||||
#define BACKLIGHT_DT 0.25 |
||||
#define BACKLIGHT_TS 2.00 |
||||
|
||||
|
||||
QWidget * home_widget() { |
||||
QVBoxLayout *main_layout = new QVBoxLayout(); |
||||
main_layout->setContentsMargins(sbr_w + 50, 50, 50, 50); |
||||
|
||||
// header
|
||||
QHBoxLayout *header_layout = new QHBoxLayout(); |
||||
QString date_str = QDateTime::currentDateTime().toString("dddd, MMMM d"); |
||||
QLabel *date = new QLabel(date_str); |
||||
date->setStyleSheet(R"(font-size: 55px;)"); |
||||
header_layout->addWidget(date, 0, Qt::AlignTop | Qt::AlignLeft); |
||||
|
||||
QLabel *version = new QLabel(QString::fromStdString("openpilot v" + Params().get("Version"))); |
||||
version->setStyleSheet(R"(font-size: 45px;)"); |
||||
header_layout->addWidget(version, 0, Qt::AlignTop | Qt::AlignRight); |
||||
|
||||
main_layout->addLayout(header_layout); |
||||
|
||||
// center
|
||||
QLabel *drive = new QLabel("Drive me"); |
||||
drive->setStyleSheet(R"(font-size: 175px;)"); |
||||
main_layout->addWidget(drive, 1, Qt::AlignHCenter); |
||||
|
||||
QWidget *w = new QWidget(); |
||||
w->setLayout(main_layout); |
||||
w->setStyleSheet(R"( |
||||
* { |
||||
background-color: none; |
||||
} |
||||
)"); |
||||
return w; |
||||
} |
||||
|
||||
HomeWindow::HomeWindow(QWidget *parent) : QWidget(parent) { |
||||
|
||||
layout = new QGridLayout; |
||||
layout->setMargin(0); |
||||
|
||||
glWindow = new GLWindow(this); |
||||
layout->addWidget(glWindow, 0, 0); |
||||
|
||||
home = home_widget(); |
||||
layout->addWidget(home, 0, 0); |
||||
QObject::connect(glWindow, SIGNAL(offroadTransition(bool)), this, SLOT(setVisibility(bool))); |
||||
|
||||
setLayout(layout); |
||||
setStyleSheet(R"( |
||||
* { |
||||
color: white; |
||||
} |
||||
)"); |
||||
} |
||||
|
||||
void HomeWindow::setVisibility(bool offroad) { |
||||
home->setVisible(offroad); |
||||
} |
||||
|
||||
void HomeWindow::mousePressEvent(QMouseEvent *e) { |
||||
UIState *ui_state = glWindow->ui_state; |
||||
|
||||
glWindow->wake(); |
||||
|
||||
// Settings button click
|
||||
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.viz_rect.x - bdr_s)){ |
||||
ui_state->scene.uilayout_sidebarcollapsed = !ui_state->scene.uilayout_sidebarcollapsed; |
||||
} |
||||
} |
||||
|
||||
|
||||
static void handle_display_state(UIState *s, int dt, bool user_input) { |
||||
static int awake_timeout = 0; |
||||
awake_timeout = std::max(awake_timeout-dt, 0); |
||||
|
||||
if (user_input || s->ignition || s->started) { |
||||
s->awake = true; |
||||
awake_timeout = 30*UI_FREQ; |
||||
} else if (awake_timeout == 0){ |
||||
s->awake = false; |
||||
} |
||||
} |
||||
|
||||
static void set_backlight(int brightness){ |
||||
std::ofstream brightness_control("/sys/class/backlight/panel0-backlight/brightness"); |
||||
if (brightness_control.is_open()){ |
||||
brightness_control << brightness << "\n"; |
||||
brightness_control.close(); |
||||
} |
||||
} |
||||
|
||||
|
||||
GLWindow::GLWindow(QWidget *parent) : QOpenGLWidget(parent) { |
||||
timer = new QTimer(this); |
||||
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate())); |
||||
|
||||
backlight_timer = new QTimer(this); |
||||
QObject::connect(backlight_timer, SIGNAL(timeout()), this, SLOT(backlightUpdate())); |
||||
|
||||
int result = read_param(&brightness_b, "BRIGHTNESS_B", true); |
||||
result += read_param(&brightness_m, "BRIGHTNESS_M", true); |
||||
if(result != 0) { |
||||
brightness_b = 200.0; |
||||
brightness_m = 10.0; |
||||
} |
||||
smooth_brightness = 512; |
||||
} |
||||
|
||||
GLWindow::~GLWindow() { |
||||
makeCurrent(); |
||||
doneCurrent(); |
||||
} |
||||
|
||||
void GLWindow::initializeGL() { |
||||
initializeOpenGLFunctions(); |
||||
std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; |
||||
std::cout << "OpenGL vendor: " << glGetString(GL_VENDOR) << std::endl; |
||||
std::cout << "OpenGL renderer: " << glGetString(GL_RENDERER) << std::endl; |
||||
std::cout << "OpenGL language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; |
||||
|
||||
ui_state = new UIState(); |
||||
ui_state->sound = &sound; |
||||
ui_state->fb_w = vwp_w; |
||||
ui_state->fb_h = vwp_h; |
||||
ui_init(ui_state); |
||||
|
||||
wake(); |
||||
|
||||
timer->start(0); |
||||
backlight_timer->start(BACKLIGHT_DT * 100); |
||||
} |
||||
|
||||
void GLWindow::backlightUpdate(){ |
||||
// Update brightness
|
||||
float k = (BACKLIGHT_DT / BACKLIGHT_TS) / (1.0f + BACKLIGHT_DT / BACKLIGHT_TS); |
||||
|
||||
float clipped_brightness = std::min(1023.0f, (ui_state->light_sensor*brightness_m) + brightness_b); |
||||
smooth_brightness = clipped_brightness * k + smooth_brightness * (1.0f - k); |
||||
int brightness = smooth_brightness; |
||||
|
||||
if (!ui_state->awake){ |
||||
brightness = 0; |
||||
} |
||||
|
||||
std::thread{set_backlight, brightness}.detach(); |
||||
} |
||||
|
||||
void GLWindow::timerUpdate() { |
||||
if (ui_state->started != onroad){ |
||||
onroad = ui_state->started; |
||||
emit offroadTransition(!onroad); |
||||
#ifdef QCOM2 |
||||
timer->setInterval(onroad ? 0 : 1000); |
||||
#endif |
||||
} |
||||
|
||||
// Fix awake timeout if running 1 Hz when offroad
|
||||
int dt = timer->interval() == 0 ? 1 : 20; |
||||
handle_display_state(ui_state, dt, false); |
||||
|
||||
ui_update(ui_state); |
||||
repaint(); |
||||
} |
||||
|
||||
void GLWindow::resizeGL(int w, int h) { |
||||
std::cout << "resize " << w << "x" << h << std::endl; |
||||
} |
||||
|
||||
void GLWindow::paintGL() { |
||||
ui_draw(ui_state); |
||||
} |
||||
|
||||
void GLWindow::wake(){ |
||||
// UI state might not be initialized yet
|
||||
if (ui_state != nullptr){ |
||||
handle_display_state(ui_state, 1, true); |
||||
} |
||||
} |
||||
|
||||
GLuint visionimg_to_gl(const VisionImg *img, EGLImageKHR *pkhr, void **pph) { |
||||
unsigned int texture; |
||||
glGenTextures(1, &texture); |
||||
glBindTexture(GL_TEXTURE_2D, texture); |
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, *pph); |
||||
glGenerateMipmap(GL_TEXTURE_2D); |
||||
*pkhr = (EGLImageKHR)1; // not NULL
|
||||
return texture; |
||||
} |
||||
|
||||
void visionimg_destroy_gl(EGLImageKHR khr, void *ph) { |
||||
// empty
|
||||
} |
||||
|
||||
FramebufferState* framebuffer_init(const char* name, int32_t layer, int alpha, |
||||
int *out_w, int *out_h) { |
||||
return (FramebufferState*)1; // not null
|
||||
} |
@ -0,0 +1,73 @@ |
||||
#pragma once |
||||
|
||||
#include <QTimer> |
||||
#include <QWidget> |
||||
#include <QGridLayout> |
||||
#include <QStackedWidget> |
||||
#include <QOpenGLWidget> |
||||
#include <QOpenGLFunctions> |
||||
|
||||
#include "qt_sound.hpp" |
||||
#include "ui/ui.hpp" |
||||
|
||||
|
||||
// container window for onroad NVG UI
|
||||
class GLWindow : public QOpenGLWidget, protected QOpenGLFunctions { |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
using QOpenGLWidget::QOpenGLWidget; |
||||
explicit GLWindow(QWidget *parent = 0); |
||||
void wake(); |
||||
~GLWindow(); |
||||
|
||||
UIState *ui_state = nullptr; |
||||
|
||||
signals: |
||||
void offroadTransition(bool offroad); |
||||
|
||||
protected: |
||||
void initializeGL() override; |
||||
void resizeGL(int w, int h) override; |
||||
void paintGL() override; |
||||
|
||||
private: |
||||
QTimer *timer; |
||||
QTimer *backlight_timer; |
||||
|
||||
QtSound sound; |
||||
|
||||
bool onroad = true; |
||||
|
||||
// TODO: this shouldn't be here
|
||||
float brightness_b = 0; |
||||
float brightness_m = 0; |
||||
float smooth_brightness = 0; |
||||
|
||||
public slots: |
||||
void timerUpdate(); |
||||
void backlightUpdate(); |
||||
}; |
||||
|
||||
|
||||
class HomeWindow : public QWidget { |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit HomeWindow(QWidget *parent = 0); |
||||
GLWindow *glWindow; |
||||
|
||||
signals: |
||||
void openSettings(); |
||||
|
||||
protected: |
||||
void mousePressEvent(QMouseEvent *e) override; |
||||
|
||||
private: |
||||
QWidget *home; |
||||
QGridLayout *layout; |
||||
|
||||
private slots: |
||||
void setVisibility(bool offroad); |
||||
}; |
||||
|
Loading…
Reference in new issue