ui: auto-hide UI buttons (#67)

* draft

* only in dlp button for now

* update with uiState

* Revert "update with uiState"

This reverts commit cbc755f0601c2595f7357c61a486c570000ecb3c.

* independent variable

* it works!

* faster

* prep for other elements

* apply to brightness checks

* proper

* lasts 30 seconds for now

* init at -1

* fade in when first tapped

* fade in finish at 250ms

* fade in finish at 100ms

* gate behind a toggle now

* redisplay button if tapped before disappear

* apply on gac

* only allow press when at 100% opacity
This commit is contained in:
Jason Wen
2023-03-31 23:30:31 -04:00
committed by GitHub
parent 72ba1c3e39
commit 18e36f3b7f
6 changed files with 99 additions and 32 deletions
+16 -6
View File
@@ -81,14 +81,24 @@ void HomeWindow::showDriverView(bool show) {
}
void HomeWindow::mousePressEvent(QMouseEvent* e) {
// Handle sidebar collapsing
if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
if (uiState()->scene.started) {
if (uiState()->scene.onroadScreenOff != -2) {
uiState()->scene.touched2 = true;
QTimer::singleShot(500, []() { uiState()->scene.touched2 = false; });
}
if (uiState()->scene.button_auto_hide) {
uiState()->scene.touch_to_wake = true;
uiState()->scene.sleep_btn_fading_in = true;
QTimer::singleShot(500, []() { uiState()->scene.touch_to_wake = false; });
}
}
if (uiState()->scene.started && uiState()->scene.onroadScreenOff != -2) {
uiState()->scene.touched2 = true;
QTimer::singleShot(500, []() { uiState()->scene.touched2 = false; });
// Handle sidebar collapsing
if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
if ((uiState()->scene.sleep_btn != 0 && uiState()->scene.sleep_btn_opacity != 0) ||
(uiState()->scene.sleep_time != 0 && uiState()->scene.onroadScreenOff != -2)) {
sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
}
}
}
@@ -594,6 +594,16 @@ SPVisualsPanel::SPVisualsPanel(QWidget *parent) : QWidget(parent) {
main_layout->addWidget(devUiMain);
// Visuals: Auto-Hide UI Button
main_layout->addWidget(horizontal_line());
main_layout->addWidget(new ParamControl(
"ButtonAutoHide",
tr("Auto-Hide UI Buttons"),
tr("Hide UI buttons on driving screen after a 30-second timeout. Tap on the screen at anytime to reveal the UI buttons."),
"../assets/offroad/icon_road.png"
));
// Visuals: OSM: Show debug UI elements
main_layout->addWidget(horizontal_line());
main_layout->addWidget(new ParamControl(
+16 -14
View File
@@ -160,13 +160,13 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) {
QRect debug_tap_rect = QRect(rect().center().x() - 200, rect().center().y() - 200, 400, 400);
QRect speed_limit_touch_rect = speed_sgn_rc.adjusted(-50, -50, 50, 50);
if (scene.dynamic_lane_profile_toggle && dlp_btn_rect.contains(e->x(), e->y())) {
if (scene.dynamic_lane_profile_toggle && scene.sleep_btn_opacity == 20 && dlp_btn_rect.contains(e->x(), e->y())) {
scene.dynamic_lane_profile++;
scene.dynamic_lane_profile = scene.dynamic_lane_profile > 2 ? 0 : scene.dynamic_lane_profile;
params.put("DynamicLaneProfile", std::to_string(scene.dynamic_lane_profile));
propagate_event = false;
} else if (scene.gac && scene.gac_mode != 0 && scene.longitudinal_control && !controls_state.getExperimentalMode() &&
car_state.getCruiseState().getAvailable() && gac_btn_rect.contains(e->x(), e->y())) {
car_state.getCruiseState().getAvailable() && scene.sleep_btn_opacity == 20 && gac_btn_rect.contains(e->x(), e->y())) {
scene.gac_tr--;
scene.gac_tr = scene.gac_tr < scene.gac_min ? scene.gac_max : scene.gac_tr;
params.put("GapAdjustCruiseTr", std::to_string(scene.gac_tr));
@@ -470,6 +470,8 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
setProperty("liveValid", ltp.getLiveValid());
// ############################## DEV UI END ##############################
setProperty("btnPerc", s.scene.sleep_btn_opacity * 0.05);
// update engageability/experimental mode button
experimental_btn->updateState(s);
@@ -855,27 +857,27 @@ void AnnotatedCameraWidget::drawVisionTurnControllerUI(QPainter &p, int x, int y
void AnnotatedCameraWidget::drawDlpButton(QPainter &p, int x, int y, int w, int h) {
int prev_dynamic_lane_profile = -1;
QString dlp_text = "";
QColor dlp_border = QColor(255, 255, 255, 255);
QColor dlp_border = QColor(255, 255, 255, (255 * btnPerc));
if (prev_dynamic_lane_profile != dynamicLaneProfile) {
prev_dynamic_lane_profile = dynamicLaneProfile;
if (dynamicLaneProfile == 0) {
dlp_text = tr("Lane\nonly");
dlp_border = QColor("#2020f8");
dlp_border = QColor(32, 32, 248, (255 * btnPerc));
} else if (dynamicLaneProfile == 1) {
dlp_text = tr("Lane\nless");
dlp_border = QColor("#0df87a");
dlp_border = QColor(13, 248, 122, (255 * btnPerc));
} else if (dynamicLaneProfile == 2) {
dlp_text = tr("Auto\nLane");
dlp_border = QColor("#0df8f8");
dlp_border = QColor(13, 248, 248, (255 * btnPerc));
}
}
QRect dlpBtn(x, y, w, h);
p.setPen(QPen(dlp_border, 6));
p.setBrush(QColor(75, 75, 75, 75));
p.setBrush(QColor(75, 75, 75, (75 * btnPerc)));
p.drawEllipse(dlpBtn);
p.setPen(QColor(Qt::white));
p.setPen(QColor(255, 255, 255, (255 * btnPerc)));
configFont(p, "Inter", 36, "SemiBold");
p.drawText(dlpBtn, Qt::AlignCenter, dlp_text);
}
@@ -883,27 +885,27 @@ void AnnotatedCameraWidget::drawDlpButton(QPainter &p, int x, int y, int w, int
void AnnotatedCameraWidget::drawGacButton(QPainter &p, int x, int y, int w, int h) {
int prev_gac_tr = -1;
QString gac_text = "";
QColor gac_border = QColor(255, 255, 255, 255);
QColor gac_border = QColor(255, 255, 255, (255 * btnPerc));
if (prev_gac_tr != gacTr) {
prev_gac_tr = gacTr;
if (gacTr == 1) {
gac_text = "Aggro\nGap";
gac_border = QColor("#ff4b4b");
gac_border = QColor(255, 75, 75, (255 * btnPerc));
} else if (gacTr == 2) {
gac_text = "Mild\nGap";
gac_border = QColor("#fcff4b");
gac_border = QColor(252, 255, 75, (255 * btnPerc));
} else {
gac_text = "Stock\nGap";
gac_border = QColor("#4bff66");
gac_border = QColor(75, 255, 102, (255 * btnPerc));
}
}
QRect gacBtn(x, y, w, h);
p.setPen(QPen(gac_border, 6));
p.setBrush(QColor(75, 75, 75, 75));
p.setBrush(QColor(75, 75, 75, (75 * btnPerc)));
p.drawEllipse(gacBtn);
p.setPen(QColor(Qt::white));
p.setPen(QColor(255, 255, 255, (255 * btnPerc)));
configFont(p, "Inter", 36, "SemiBold");
p.drawText(gacBtn, Qt::AlignCenter, gac_text);
}
+4
View File
@@ -137,6 +137,8 @@ class AnnotatedCameraWidget : public CameraWidget {
Q_PROPERTY(bool liveValid MEMBER liveValid);
// ############################## DEV UI END ##############################
Q_PROPERTY(float btnPerc MEMBER btnPerc);
public:
explicit AnnotatedCameraWidget(VisionStreamType type, QWidget* parent = 0);
void updateState(const UIState &s);
@@ -263,6 +265,8 @@ private:
bool liveValid;
// ############################## DEV UI END ##############################
float btnPerc;
protected:
void paintGL() override;
void initializeGL() override;
+46 -10
View File
@@ -248,6 +248,7 @@ void ui_update_params(UIState *s) {
s->scene.gac_max = std::atoi(params.get("GapAdjustCruiseMax").c_str());
s->scene.dev_ui_enabled = params.getBool("DevUI");
s->scene.dev_ui_info = std::atoi(params.get("DevUIInfo").c_str());
s->scene.button_auto_hide = params.getBool("ButtonAutoHide");
if (s->scene.onroadScreenOff > 0) {
s->scene.osoTimer = s->scene.onroadScreenOff * 60 * UI_FREQ;
@@ -296,6 +297,50 @@ void UIState::updateStatus() {
emit primeTypeChanged(prime_type);
Params().put("PrimeType", std::to_string(prime_type));
}
if (scene.started) {
if (scene.button_auto_hide) {
if (scene.touch_to_wake) {
scene.sleep_btn = 30 * UI_FREQ;
} else if (scene.sleep_btn > 0) {
scene.sleep_btn--;
} else if (scene.sleep_btn == -1) {
scene.sleep_btn = 30 * UI_FREQ;
}
// Check if the sleep button should be fading in
if (scene.sleep_btn_fading_in) {
// Increase the opacity of the sleep button by a small amount
if (scene.sleep_btn_opacity < 20) {
scene.sleep_btn_opacity+= 10;
}
if (scene.sleep_btn_opacity >= 20) {
// If the opacity has reached its maximum value, stop fading in
scene.sleep_btn_fading_in = false;
scene.sleep_btn_opacity = 20;
}
} else if (scene.sleep_btn == 0) {
// Fade out the sleep button as before
if (scene.sleep_btn_opacity > 0) {
scene.sleep_btn_opacity-= 2;
}
} else {
// Set the opacity of the sleep button to its maximum value
scene.sleep_btn_opacity = 20;
}
} else {
scene.sleep_btn_opacity = 20;
}
if (scene.onroadScreenOff != -2 && scene.touched2) {
scene.sleep_time = scene.osoTimer;
} else if (scene.controlsState.getAlertSize() != cereal::ControlsState::AlertSize::NONE && scene.onroadScreenOff != -2) {
scene.sleep_time = scene.osoTimer;
} else if (scene.sleep_time > 0 && scene.onroadScreenOff != -2) {
scene.sleep_time--;
} else if (scene.sleep_time == -1 && scene.onroadScreenOff != -2) {
scene.sleep_time = scene.osoTimer;
}
}
}
UIState::UIState(QObject *parent) : QObject(parent) {
@@ -369,21 +414,12 @@ void Device::updateBrightness(const UIState &s) {
// Scale back to 10% to 100%
clipped_brightness = std::clamp(100.0f * clipped_brightness, 10.0f, 100.0f);
if (s.scene.onroadScreenOff != -2 && s.scene.touched2) {
sleep_time = s.scene.osoTimer;
} else if (s.scene.controlsState.getAlertSize() != cereal::ControlsState::AlertSize::NONE && s.scene.onroadScreenOff != -2) {
sleep_time = s.scene.osoTimer;
} else if (sleep_time > 0 && s.scene.onroadScreenOff != -2) {
sleep_time--;
} else if (s.scene.started && sleep_time == -1 && s.scene.onroadScreenOff != -2) {
sleep_time = s.scene.osoTimer;
}
}
int brightness = brightness_filter.update(clipped_brightness);
if (!awake) {
brightness = 0;
} else if (s.scene.started && sleep_time == 0 && s.scene.onroadScreenOff != -2) {
} else if (s.scene.started && s.scene.sleep_time == 0 && s.scene.onroadScreenOff != -2) {
brightness = s.scene.onroadScreenOffBrightness * 0.01 * brightness;
} else if (s.scene.brightness) {
brightness = s.scene.brightness * 0.99;
+7 -2
View File
@@ -159,6 +159,7 @@ typedef struct UIScene {
bool visual_brake_lights;
int onroadScreenOff, osoTimer, brightness, onroadScreenOffBrightness, awake;
int sleep_time = -1;
bool touched2 = false;
bool stand_still_timer;
@@ -176,6 +177,12 @@ typedef struct UIScene {
int rn_offset;
bool live_torque_toggle;
bool custom_torque_toggle;
bool touch_to_wake = false;
int sleep_btn = -1;
bool sleep_btn_fading_in = false;
int sleep_btn_opacity = 20;
bool button_auto_hide;
} UIScene;
class UIState : public QObject {
@@ -240,8 +247,6 @@ private:
bool motionTriggered(const UIState &s);
void setAwake(bool on);
int sleep_time = -1;
signals:
void displayPowerChanged(bool on);
void interactiveTimout();