# include "selfdrive/ui/qt/home.h"
# include <QHBoxLayout>
# include <QMouseEvent>
# include <QStackedWidget>
# include <QVBoxLayout>
# include "selfdrive/ui/qt/offroad/experimental_mode.h"
# include "selfdrive/ui/qt/util.h"
# include "selfdrive/ui/qt/widgets/prime.h"
// HomeWindow: the container for the offroad and onroad UIs
HomeWindow : : HomeWindow ( QWidget * parent ) : QWidget ( parent ) {
QHBoxLayout * main_layout = new QHBoxLayout ( this ) ;
main_layout - > setMargin ( 0 ) ;
main_layout - > setSpacing ( 0 ) ;
sidebar = new Sidebar ( this ) ;
main_layout - > addWidget ( sidebar ) ;
QObject : : connect ( sidebar , & Sidebar : : openSettings , this , & HomeWindow : : openSettings ) ;
slayout = new QStackedLayout ( ) ;
main_layout - > addLayout ( slayout ) ;
home = new OffroadHome ( this ) ;
QObject : : connect ( home , & OffroadHome : : openSettings , this , & HomeWindow : : openSettings ) ;
slayout - > addWidget ( home ) ;
onroad = new OnroadWindow ( this ) ;
slayout - > addWidget ( onroad ) ;
body = new BodyWindow ( this ) ;
slayout - > addWidget ( body ) ;
driver_view = new DriverViewWindow ( this ) ;
connect ( driver_view , & DriverViewWindow : : done , [ = ] {
showDriverView ( false ) ;
} ) ;
slayout - > addWidget ( driver_view ) ;
setAttribute ( Qt : : WA_NoSystemBackground ) ;
QObject : : connect ( uiState ( ) , & UIState : : uiUpdate , this , & HomeWindow : : updateState ) ;
QObject : : connect ( uiState ( ) , & UIState : : offroadTransition , this , & HomeWindow : : offroadTransition ) ;
QObject : : connect ( uiState ( ) , & UIState : : offroadTransition , sidebar , & Sidebar : : offroadTransition ) ;
}
void HomeWindow : : showSidebar ( bool show ) {
sidebar - > setVisible ( show ) ;
}
void HomeWindow : : updateState ( const UIState & s ) {
const SubMaster & sm = * ( s . sm ) ;
// switch to the generic robot UI
if ( onroad - > isVisible ( ) & & ! body - > isEnabled ( ) & & sm [ " carParams " ] . getCarParams ( ) . getNotCar ( ) ) {
body - > setEnabled ( true ) ;
slayout - > setCurrentWidget ( body ) ;
}
}
void HomeWindow : : offroadTransition ( bool offroad ) {
body - > setEnabled ( false ) ;
sidebar - > setVisible ( offroad ) ;
if ( offroad ) {
slayout - > setCurrentWidget ( home ) ;
} else {
slayout - > setCurrentWidget ( onroad ) ;
}
}
void HomeWindow : : showDriverView ( bool show ) {
if ( show ) {
emit closeSettings ( ) ;
slayout - > setCurrentWidget ( driver_view ) ;
} else {
slayout - > setCurrentWidget ( home ) ;
}
sidebar - > setVisible ( show = = false ) ;
}
void HomeWindow : : mousePressEvent ( QMouseEvent * e ) {
// Handle sidebar collapsing
if ( ( onroad - > isVisible ( ) | | body - > isVisible ( ) ) & & ( ! sidebar - > isVisible ( ) | | e - > x ( ) > sidebar - > width ( ) ) ) {
sidebar - > setVisible ( ! sidebar - > isVisible ( ) ) ;
}
}
void HomeWindow : : mouseDoubleClickEvent ( QMouseEvent * e ) {
HomeWindow : : mousePressEvent ( e ) ;
const SubMaster & sm = * ( uiState ( ) - > sm ) ;
if ( sm [ " carParams " ] . getCarParams ( ) . getNotCar ( ) ) {
if ( onroad - > isVisible ( ) ) {
slayout - > setCurrentWidget ( body ) ;
} else if ( body - > isVisible ( ) ) {
slayout - > setCurrentWidget ( onroad ) ;
}
showSidebar ( false ) ;
}
}
// OffroadHome: the offroad home page
OffroadHome : : OffroadHome ( QWidget * parent ) : QFrame ( parent ) {
QVBoxLayout * main_layout = new QVBoxLayout ( this ) ;
main_layout - > setContentsMargins ( 40 , 40 , 40 , 40 ) ;
// top header
QHBoxLayout * header_layout = new QHBoxLayout ( ) ;
header_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
header_layout - > setSpacing ( 16 ) ;
update_notif = new QPushButton ( tr ( " UPDATE " ) ) ;
update_notif - > setVisible ( false ) ;
update_notif - > setStyleSheet ( " background-color: #364DEF; " ) ;
QObject : : connect ( update_notif , & QPushButton : : clicked , [ = ] ( ) { center_layout - > setCurrentIndex ( 1 ) ; } ) ;
header_layout - > addWidget ( update_notif , 0 , Qt : : AlignHCenter | Qt : : AlignLeft ) ;
alert_notif = new QPushButton ( ) ;
alert_notif - > setVisible ( false ) ;
alert_notif - > setStyleSheet ( " background-color: #E22C2C; " ) ;
QObject : : connect ( alert_notif , & QPushButton : : clicked , [ = ] { center_layout - > setCurrentIndex ( 2 ) ; } ) ;
header_layout - > addWidget ( alert_notif , 0 , Qt : : AlignHCenter | Qt : : AlignLeft ) ;
version = new ElidedLabel ( ) ;
header_layout - > addWidget ( version , 0 , Qt : : AlignHCenter | Qt : : AlignRight ) ;
main_layout - > addLayout ( header_layout ) ;
// main content
main_layout - > addSpacing ( 25 ) ;
center_layout = new QStackedLayout ( ) ;
QWidget * home_widget = new QWidget ( this ) ;
{
QHBoxLayout * home_layout = new QHBoxLayout ( home_widget ) ;
home_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
home_layout - > setSpacing ( 30 ) ;
// left: PrimeAdWidget
QStackedWidget * left_widget = new QStackedWidget ( this ) ;
QVBoxLayout * left_prime_layout = new QVBoxLayout ( ) ;
left_prime_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
QWidget * prime_user = new PrimeUserWidget ( ) ;
prime_user - > setStyleSheet ( R " (
border - radius : 10 px ;
background - color : # 333333 ;
) " );
left_prime_layout - > addWidget ( prime_user ) ;
left_prime_layout - > addStretch ( ) ;
left_widget - > addWidget ( new LayoutWidget ( left_prime_layout ) ) ;
left_widget - > addWidget ( new PrimeAdWidget ) ;
left_widget - > setStyleSheet ( " border-radius: 10px; " ) ;
connect ( uiState ( ) - > prime_state , & PrimeState : : changed , [ left_widget ] ( ) {
left_widget - > setCurrentIndex ( uiState ( ) - > prime_state - > isSubscribed ( ) ? 0 : 1 ) ;
} ) ;
home_layout - > addWidget ( left_widget , 1 ) ;
// right: ExperimentalModeButton, SetupWidget
QWidget * right_widget = new QWidget ( this ) ;
QVBoxLayout * right_column = new QVBoxLayout ( right_widget ) ;
right_column - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
right_widget - > setFixedWidth ( 750 ) ;
right_column - > setSpacing ( 30 ) ;
ExperimentalModeButton * experimental_mode = new ExperimentalModeButton ( this ) ;
QObject : : connect ( experimental_mode , & ExperimentalModeButton : : openSettings , this , & OffroadHome : : openSettings ) ;
right_column - > addWidget ( experimental_mode , 1 ) ;
SetupWidget * setup_widget = new SetupWidget ;
QObject : : connect ( setup_widget , & SetupWidget : : openSettings , this , & OffroadHome : : openSettings ) ;
right_column - > addWidget ( setup_widget , 1 ) ;
home_layout - > addWidget ( right_widget , 1 ) ;
}
center_layout - > addWidget ( home_widget ) ;
// add update & alerts widgets
update_widget = new UpdateAlert ( ) ;
QObject : : connect ( update_widget , & UpdateAlert : : dismiss , [ = ] ( ) { center_layout - > setCurrentIndex ( 0 ) ; } ) ;
center_layout - > addWidget ( update_widget ) ;
alerts_widget = new OffroadAlert ( ) ;
QObject : : connect ( alerts_widget , & OffroadAlert : : dismiss , [ = ] ( ) { center_layout - > setCurrentIndex ( 0 ) ; } ) ;
center_layout - > addWidget ( alerts_widget ) ;
main_layout - > addLayout ( center_layout , 1 ) ;
// set up refresh timer
timer = new QTimer ( this ) ;
timer - > callOnTimeout ( this , & OffroadHome : : refresh ) ;
setStyleSheet ( R " (
* {
color : white ;
}
OffroadHome {
background - color : black ;
}
OffroadHome > QPushButton {
padding : 15 px 30 px ;
border - radius : 5 px ;
font - size : 40 px ;
font - weight : 500 ;
}
OffroadHome > QLabel {
font - size : 55 px ;
}
) " );
}
void OffroadHome : : showEvent ( QShowEvent * event ) {
refresh ( ) ;
timer - > start ( 10 * 1000 ) ;
}
void OffroadHome : : hideEvent ( QHideEvent * event ) {
timer - > stop ( ) ;
}
void OffroadHome : : refresh ( ) {
version - > setText ( getBrand ( ) + " " + QString : : fromStdString ( params . get ( " UpdaterCurrentDescription " ) ) ) ;
bool updateAvailable = update_widget - > refresh ( ) ;
int alerts = alerts_widget - > refresh ( ) ;
// pop-up new notification
int idx = center_layout - > currentIndex ( ) ;
if ( ! updateAvailable & & ! alerts ) {
idx = 0 ;
} else if ( updateAvailable & & ( ! update_notif - > isVisible ( ) | | ( ! alerts & & idx = = 2 ) ) ) {
idx = 1 ;
} else if ( alerts & & ( ! alert_notif - > isVisible ( ) | | ( ! updateAvailable & & idx = = 1 ) ) ) {
idx = 2 ;
}
center_layout - > setCurrentIndex ( idx ) ;
update_notif - > setVisible ( updateAvailable ) ;
alert_notif - > setVisible ( alerts ) ;
if ( alerts ) {
alert_notif - > setText ( QString : : number ( alerts ) + ( alerts > 1 ? tr ( " ALERTS " ) : tr ( " ALERT " ) ) ) ;
}
}